Handling of floating point numbers changed from GMP 4.1.4 to GMP 4.2.1
Torbjorn Granlund
tg at swox.com
Wed Sep 12 14:03:56 CEST 2007
./bug-gmp-4.2.1
./bug-gmp-4.1.4
This prints
real_coeff = 137171200400403985/1125899906842624
float = 121.83249999999999602
real_coeff = 137171200400403985/1125899906842624
float = 121.83250000000001023
OK, so it seems GMP 4.1.4 did not comply to the documentation (or your
compiler uses the wrong fp->unsigned instruction, not uncommon!). I
don't recall this specifically, but I do recall that we rewrote much
of this code, for speed and perhaps for correctness.
IIRC, C is defined to always do truncation for float -> int assignments, so
no matter the rounding mode,
intvar = 1.999999;
should put 1 in intvar.
The mismatch does not happen if one does not touch the rounding mode
or if one sets it to FE_TONEAREST, FE_TOWARDZERO, FE_DOWNWARD.
So, on this example, while GMP 4.1.4 results do not depend on the
rounding mode, with GMP 4.2.1 the rounding mode matters.
I think you've got it backwards.
(I tested this with GMP 4.2.2 on my x86_64 system and see no problems.
I have not tried GMP 4.1.4, but if your output is not mixed up, it is
GMP 4.1.4 that misbehaves for you.)
Perhaps the answer is simply that GMP provides no guarantee
when invoked with the rounding mode set to anything different from
FE_TONEAREST, but I have not found that in the documentation.
Instead, the documentation says, e.g., that
double mpq_get_d (mpq_t op)
Convert op to a double, truncating if necessary (ie.: rounding towards zero).
Well, we don't provide a guarantee, but we do have very strong
feelings about complying to our own documentation. :-)
--
Torbjörn
More information about the gmp-discuss
mailing list