GMP4.3.1, GCC 4.4.1 and denormalized double

Torbjorn Granlund tg at gmplib.org
Fri Oct 23 15:48:04 CEST 2009


Norbert Mueller <mueller at uni-trier.de> writes:

  There seems to be an error in the 64-bit verison of gmp 4.3.1 (or in gcc 
  4.4.1.) when trying to convert from mpf to double in case the result is not 
  normalized. For a detailed bug report see below.

Thanks for an exemplary bug report!

This was a bug in GMP affecting denorms on 64-bit hosts.  A special case
for 64-bit machines was completely wrong.

The following patch should correct it.  This change looks biger than it
is, but there are just two lines that really changed, the rest is a
slight reorg of the code to avoid spurious warnings.

Please follow up to confirm that the bug really seem to be gone for you
too.
  
diff -r 45d387b60a6c mpn/generic/get_d.c
--- a/mpn/generic/get_d.c	Fri Oct 23 14:54:26 2009 +0200
+++ b/mpn/generic/get_d.c	Fri Oct 23 15:44:30 2009 +0200
@@ -271,30 +271,27 @@
       }
     else if (UNLIKELY (exp <= CONST_NEG_1023))
       {
-	int rshift = GMP_LIMB_BITS - lshift;
+	int rshift;
 
 	if (LIKELY (exp <= CONST_NEG_1022_SUB_53))
 	  return 0.0;	 /* denorm underflows to zero */
 
 	rshift = -1022 - exp;
 	ASSERT (rshift > 0 && rshift < 53);
-	if (GMP_LIMB_BITS == 64)
+#if GMP_LIMB_BITS > 53
+	mlo >>= rshift;
+	mhi = mlo >> 32;
+#else
+	if (rshift >= 32)
 	  {
-	    mlo = (mlo >> rshift) | (mhi << lshift);
-	    mhi >>= rshift;
+	    mlo = mhi;
+	    mhi = 0;
+	    rshift -= 32;
 	  }
-	else
-	  {
-	    if (rshift >= 32)
-	      {
-		mlo = mhi;
-		mhi = 0;
-		rshift -= 32;
-	      }
-	    lshift = GMP_LIMB_BITS - rshift;
-	    mlo = (mlo >> rshift) | (rshift == 0 ? 0 : mhi << lshift);
-	    mhi >>= rshift;
-	  }
+	lshift = GMP_LIMB_BITS - rshift;
+	mlo = (mlo >> rshift) | (rshift == 0 ? 0 : mhi << lshift);
+	mhi >>= rshift;
+#endif
 	exp = -1023;
       }
   }

-- 
Torbjörn


More information about the gmp-bugs mailing list