问题
What is the correct syntax for using printf
and its cousins sprintf
and fprintf
to display the value of mpreal
-type variables? I have tried the naive casting to double:
printf ("... %g ...", (double) var);
only to receive this error message from g++:
error: invalid cast from type ‘mpfr::mpreal’ to type ‘double’
I had no problem using double
-type variables elsewhere on the program.
I heard about the type mpreal
as part of this library intended to enable the use of the usual binary operators to perform arbitrary precision arithmetic operations.
回答1:
The mpreal
is arbitrary precision floating-point numerical type.
As such, mpreal
numbers might have much more significant digits (even hundreds or thousandths) than double
. Which means it is pointless to round mpreal
to double
before display - you will lose all the original accuracy in this case.
It is easy to display mpreal
in C++:
/* 100-digits accurate pi */
mpreal pi = mpfr::const_pi(mpfr::digits2bits(100));
/* Show 60-digits of pi */
cout.precision(60);
cout << pi;
However you can use it with printf
as well (by converting to string first):
/* 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());
Format specification for multiple-precision numbers are the same as for standard with the exception to rounding specification. You can safely use rounding to nearest,RN
as in examples above.
More details on mp-formatting are given in MPFR documentation.
(I'm author of mpreal
class aka MPFR C++)
回答2:
mpreal
is a class, not a numeric type, and it doesn't provide conversion operators to numeric types.
But it does provide member functions that perform type conversions:
long toLong() const;
unsigned long toULong() const;
double toDouble() const;
long double toLDouble() const;
So this should work:
printf ("... %g ...", var.toDouble());
or:
printf ("... %Lg ...", var.toLDouble());
(I haven't confirmed this.)
UPDATE :
An mpreal
object represents a real number that may have much greater range and/or precision than can be represented by any built-in numeric type (that's the whole point of MPFR). Converting to a numeric type makes sense only if the value is within the range of that type, and you don't care about the extra precision.
In some cases, that might be good enough, but as this answer says, you can print the full precision using either the overloaded <<
operator or the toString()
member function.
来源:https://stackoverflow.com/questions/9626810/how-to-use-printf-with-mpfr-and-mpreal