Mantissa string from mpf_get_str can be wrong in some least-significant digits
Uwe Mueller
um.computing at arcor.de
Sun Jun 28 20:15:48 CEST 2009
This bug report concerns GMP versions 4.2.1, 4.3.1 and probably also
others. It contains a test program, error description and a suggested
patch.
The issue is shown by the attached test program. It calculates the
string representation of some big numbers by the function mpf_get_str
with different values for n_digits. The respective result is compared
with the exact (n_digits = 0) result. The differences are displayed.
The test program does not take any arguments.
Error description:
------------------
For very large numbers and certain output precision,
the string representation created by function mpf_get_str
is not correct in the last few digits. The test program
displays such deviations. I give here an example:
Testing 2^10000000000000...
...
Difference found:
mpf_get_str(all): .6485629529556e+3010299956640
mpf_get_str( 13): .6485629530917e+3010299956640
...
The first value, marked with (all), is calculated from
the exact value (n_digits = 0) by rounding, while the
second value, marked with ( 13) is calculated by
mpf_get_str with n_digits = 13. There is a difference
in both values in the last 4 digits of the mantissa.
My system is running on a 64-bit AMD processor with OS x86_64
GNU/Linux and gcc version 4.1.2 20061115 (prerelease) (Debian
4.1.1-21).
In a 32-bit system (i686 GNU/Linux ,gcc version 4.3.2) the test
program gives following example:
Testing 2^2000000000...
...
Difference found:
mpf_get_str(all): .212795476e+602059992
mpf_get_str( 9): .212796198e+602059992
...
Error analysis
--------------
In my opinion, the reason is a rounding error in the calculation of
the digits. Without a deeper analysis, I tried the following patch,
which eliminated the differences, but I am not sure whether this helps
in all cases.
diff -Naur gmp-4.3.1/mpf/get_str.c gmp-4.3.1_patch/mpf/get_str.c
--- gmp-4.3.1/mpf/get_str.c 2009-05-12 06:12:12.000000000 +0000
+++ gmp-4.3.1_patch/mpf/get_str.c 2009-06-14 01:20:28.000000000 +0000
@@ -174,7 +174,7 @@
conversion.) */
tstr = (unsigned char *) TMP_ALLOC (n_digits + 2 * GMP_LIMB_BITS + 3);
- n_limbs_needed = 2 + ((mp_size_t) (n_digits /
mp_bases[base].chars_per_bit_exactly)) / GMP_NUMB_BITS;
+ n_limbs_needed = 3 + ((mp_size_t) (n_digits /
mp_bases[base].chars_per_bit_exactly)) / GMP_NUMB_BITS;
if (ue <= n_limbs_needed)
{
More information about the gmp-bugs
mailing list