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