Comment utiliser printf avec mpfr et mpreal
Question
Quelle est la syntaxe correcte pour utiliser printf
et ses cousins sprintf
et fprintf
pour afficher la valeur de mpreal
-variables de type ?J'ai essayé le casting naïf pour doubler :
printf ("... %g ...", (double) var);
seulement pour recevoir ce message d'erreur de g++ :
error: invalid cast from type ‘mpfr::mpreal’ to type ‘double’
Je n'ai eu aucun problème à utiliser double
-tapez les variables ailleurs dans le programme.
J'ai entendu parler du type mpreal
dans le cadre de cela bibliothèque destiné à permettre l'utilisation des opérateurs binaires habituels pour effectuer des opérations arithmétiques de précision arbitraire.
La solution
Le mpreal
est un type numérique à virgule flottante de précision arbitraire.
En tant que tel, mpreal
les nombres peuvent avoir des chiffres beaucoup plus significatifs (même des centaines ou des millièmes) que double
.Ce qui veut dire que c'est inutile d'arrondir mpreal
à double
avant l'affichage - dans ce cas, vous perdrez toute la précision d'origine.
Il est facile d'afficher mpreal
en C++ :
/* 100-digits accurate pi */
mpreal pi = mpfr::const_pi(mpfr::digits2bits(100));
/* Show 60-digits of pi */
cout.precision(60);
cout << pi;
Cependant, vous pouvez l'utiliser avec printf
ainsi (en convertissant d'abord en chaîne) :
/* Display all digits (default formatting) */
printf("pi = %s\n", pi.toString().c_str());
/* Custom format, 60 digits */
printf("pi = %s\n", pi.toString("%.60RNf").c_str());
/* Using native printf from MPFR*/
mpfr_printf("pi = %.60RNf\n", pi.mpfr_srcptr());
Les spécifications de format pour les nombres à précisions multiples sont les mêmes que pour les nombres standards, à l'exception de la spécification d'arrondi.Vous pouvez utiliser en toute sécurité l'arrondi au plus proche,RN
comme dans les exemples ci-dessus.
Plus de détails sur le formatage mp sont donnés dans Documentation MPFR.
(je suis l'auteur de mpreal
classe alias MPFR C++)
Autres conseils
mpreal
est une classe, pas un type numérique, et elle ne fournit pas d'opérateurs de conversion en types numériques.
Mais il fournit des fonctions membres qui effectuent des conversions de type :
long toLong() const;
unsigned long toULong() const;
double toDouble() const;
long double toLDouble() const;
Donc ça devrait marcher :
printf ("... %g ...", var.toDouble());
ou:
printf ("... %Lg ...", var.toLDouble());
(Je ne l'ai pas confirmé.)
MISE À JOUR :
Un mpreal
object représente un nombre réel qui peut avoir une plage et/ou une précision bien plus grande que celle qui peut être représentée par n'importe quel type numérique intégré (c'est tout l'intérêt de MPFR).La conversion en un type numérique n'a de sens que si la valeur se situe dans la plage de ce type et que vous ne vous souciez pas de la précision supplémentaire.
Dans certains cas, cela peut suffire, mais comme cette réponse dit, vous pouvez imprimer toute la précision en utilisant soit le fichier surchargé <<
l'opérateur ou le toString()
fonction membre.