2

I'm trying to convert MPFR number to string and then back. The code I'm using is:

int base = 10;
int input = 25;

mpfr_t number;
mpfr_inits2(53, number, (mpfr_ptr) 0);
mpfr_set_d(number, input, MPFR_RNDD);
mpfr_printf ("mpfr = %.17Rg\n", number);

char* str = NULL;
mpfr_exp_t e;
str = mpfr_get_str (NULL, &e, base, 0, number, MPFR_RNDN);

cout << "str: " << str << endl;
cout << "e: " << e << endl;

mpfr_t back;
mpfr_inits2(53, back, (mpfr_ptr) 0);
mpfr_set_str(back, str, base, MPFR_RNDD);
mpfr_set_exp(back, e);
mpfr_printf ("back = %.17Rg\n", back);

mpfr_free_str (str);

Which gives me the output:

mpfr = 25
str: 25000000000000000
e: 2
back = 2.7755575615628914

If I change the base to 2, then I get the correct output

mpfr = 25
str: 11001000000000000000000000000000000000000000000000000
e: 5
back = 25

But if I change the input to 0, I again get the wrong mpfr number back:

mpfr = 0
str: 00000000000000000000000000000000000000000000000000000
e: 0
back = 0.8125

What exactly am I doing wrong?

user1335014
  • 351
  • 1
  • 4
  • 13

1 Answers1

2

The error in your code is that e is the exponent in base base, not the one in base 2. You need something like (very simplified for this specific case, for positive numbers only):

char buffer[64];
sprintf (buffer, ".%s@%ld", str, (long) e);
mpfr_set_str (back, buffer, base, MPFR_RNDD);
mpfr_printf ("back = %.17Rg\n", back);

(The @ instead of the usual e allows the code to support bases larger than 10.)

Also note that in your third test, with input 0, you call mpfr_set_exp on the value 0, which currently yields an invalid MPFR number. In MPFR 4, mpfr_set_exp will have no effect on 0, which is cleaner.

vinc17
  • 2,829
  • 17
  • 23