How to use printf with mpfr and mpreal

怎甘沉沦 提交于 2019-12-23 01:04:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!