Cómo usar printf con mpfr y mpreal
Pregunta
¿Cuál es la sintaxis correcta para usar? printf
y sus primos sprintf
y fprintf
para mostrar el valor de mpreal
-tipo de variables?He probado el casting ingenuo para duplicar:
printf ("... %g ...", (double) var);
solo para recibir este mensaje de error de g++:
error: invalid cast from type ‘mpfr::mpreal’ to type ‘double’
No tuve problemas para usar double
-escriba variables en otras partes del programa.
Escuché sobre el tipo mpreal
como parte de esto biblioteca destinado a permitir el uso de los operadores binarios habituales para realizar operaciones aritméticas de precisión arbitraria.
Solución
El mpreal
es un tipo numérico de punto flotante de precisión arbitraria.
Como tal, mpreal
Los números pueden tener dígitos mucho más significativos (incluso centenas o milésimas) que double
.Lo que significa que es inútil redondear mpreal
a double
antes de la visualización: en este caso perderá toda la precisión original.
Es fácil de mostrar 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;
Sin embargo puedes usarlo con printf
también (convirtiendo primero a cadena):
/* 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());
Las especificaciones de formato para números de precisión múltiple son las mismas que las estándar, con la excepción de la especificación de redondeo.Puede utilizar con seguridad el redondeo al más cercano,RN
como en los ejemplos anteriores.
Se proporcionan más detalles sobre el formato mp en Documentación MPFR.
(Soy autor de mpreal
clase alias MPFR C++)
Otros consejos
mpreal
es una clase, no un tipo numérico, y no proporciona operadores de conversión a tipos numéricos.
Pero sí proporciona funciones miembro que realizan conversiones de tipos:
long toLong() const;
unsigned long toULong() const;
double toDouble() const;
long double toLDouble() const;
Entonces esto debería funcionar:
printf ("... %g ...", var.toDouble());
o:
printf ("... %Lg ...", var.toLDouble());
(No lo he confirmado).
ACTUALIZAR :
Un mpreal
El objeto representa un número real que puede tener un rango y/o precisión mucho mayor que el que puede representar cualquier tipo numérico incorporado (ese es el objetivo de MPFR).La conversión a un tipo numérico tiene sentido sólo si el valor está dentro del rango de ese tipo y no le importa la precisión adicional.
En algunos casos, eso podría ser suficiente, pero como esta respuesta dice, puedes imprimir la precisión completa usando el sobrecargado <<
operador o el toString()
función miembro.