2

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.

Sir Whiteout
  • 123
  • 1
  • 7
  • You accepted [my answer](http://stackoverflow.com/a/9627136/827263), but [Pavel's answer](http://stackoverflow.com/a/9627660/827263) is probably better (see my update). – Keith Thompson Nov 01 '13 at 01:26

2 Answers2

7

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++)

  • Hi, Thanks for your great library :) Work really great !! I wanted to ask a simple question about the answer, without parameters toString() still give me number with scientific expression (ie; e+16) for large number, the only workaround I found is with a expression like toString("%1024.1024RNf"), to be sure all digit are printed. Do you know a better method, to prevent leading 0 to be printed in example. (My need is to simply save the number to a DB to let the other program to read it like a string) – yagmoth555 May 03 '16 at 15:05
  • 1
    Without parameters toString() converts number to string with digits enough to restore it back from the produced string without accuracy loss. Do not forget to setup default precision before using mpreal/MPFR: mpfr::mpreal::set_default_prec() – Pavel Holoborodko May 04 '16 at 02:18
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.

Community
  • 1
  • 1
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631