]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix ldbl-128ibm logbl near powers of 2 (bug 18030).
authorJoseph Myers <joseph@codesourcery.com>
Thu, 26 Feb 2015 15:13:22 +0000 (15:13 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Thu, 26 Feb 2015 15:14:58 +0000 (15:14 +0000)
The ldbl-128ibm implementation of logbl produces incorrect results
when the high part of the argument is a power of 2 and the low part a
nonzero number with the opposite sign (and so the returned exponent
should be 1 less than that of the high part).  For example, logbl
(0x1.ffffffffffffffp1L) returns 2 but should return 1.  (This is
similar to (fixed) bug 16740 for frexpl, and (fixed) bug 18029 for
ilogbl.)  This patch adds checks for that case.

Tested for powerpc.

[BZ #18030]
* sysdeps/ieee754/ldbl-128ibm/s_logbl.c (__logbl): Adjust exponent
of power of 2 down when low part has opposite sign.
* math/libm-test.inc (logb_test_data): Add more tests.

ChangeLog
NEWS
math/libm-test.inc
sysdeps/ieee754/ldbl-128ibm/s_logbl.c

index 90c42c85a3622cb172b1051919645c8a4a82c8bc..ac6110b96596dbf0756f836354e5a5de503f8a53 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-26  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #18030]
+       * sysdeps/ieee754/ldbl-128ibm/s_logbl.c (__logbl): Adjust exponent
+       of power of 2 down when low part has opposite sign.
+       * math/libm-test.inc (logb_test_data): Add more tests.
+
 2015-02-26  Andreas Schwab  <schwab@suse.de>
 
        [BZ #18032]
diff --git a/NEWS b/NEWS
index 77e081464d509443afaf864e2ce3af1286371d48..f09ffb1ccd84536c7650d080e563c6a89fd6d53a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -12,7 +12,7 @@ Version 2.22
   4719, 14841, 13064, 14094, 15319, 15467, 15790, 15969, 16560, 16783,
   17269, 17523, 17569, 17588, 17792, 17836, 17912, 17916, 17932, 17944,
   17949, 17964, 17965, 17967, 17969, 17978, 17987, 17991, 17996, 17998,
-  17999, 18019, 18020, 18029, 18032.
+  17999, 18019, 18020, 18029, 18030, 18032.
 
 * Character encoding and ctype tables were updated to Unicode 7.0.0, using
   new generator scripts contributed by Pravin Satpute and Mike FABIAN (Red
index 6045764fd37efee877272875656252be3bed9009..7acd29bc136269f2ee447b5bae0c18ac69cb2ff4 100644 (file)
@@ -7868,6 +7868,11 @@ static const struct test_f_f_data logb_test_data[] =
     TEST_f_f (logb, 0x1p-16400L, -16400, NO_INEXACT_EXCEPTION),
     TEST_f_f (logb, 0x.00000000001p-16382L, -16426, NO_INEXACT_EXCEPTION),
 #endif
+
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 57
+    TEST_f_f (logb, 0x1.ffffffffffffffp1L, 1, NO_INEXACT_EXCEPTION),
+    TEST_f_f (logb, -0x1.ffffffffffffffp1L, 1, NO_INEXACT_EXCEPTION),
+#endif
   };
 
 static void
index dbd3478e6330d46160a4aaa4a26a3b6d466a5fb4..22e5fc24c0543474c9ac00b2604420e9dcba7af7 100644 (file)
 long double
 __logbl (long double x)
 {
-  int64_t hx, rhx;
-  double xhi;
+  int64_t hx, hxs, rhx;
+  double xhi, xlo;
 
-  xhi = ldbl_high (x);
+  ldbl_unpack (x, &xhi, &xlo);
   EXTRACT_WORDS64 (hx, xhi);
+  hxs = hx;
   hx &= 0x7fffffffffffffffLL;  /* high |x| */
   if (hx == 0)
     return -1.0 / fabs (x);
@@ -42,6 +43,16 @@ __logbl (long double x)
          though it were normalized.  */
       rhx -= __builtin_clzll (hx) - 12;
     }
+  else if ((hx & 0x000fffffffffffffLL) == 0)
+    {
+      /* If the high part is a power of 2, and the low part is nonzero
+        with the opposite sign, the low part affects the
+        exponent.  */
+      int64_t lx;
+      EXTRACT_WORDS64 (lx, xlo);
+      if ((hxs ^ lx) < 0 && (lx & 0x7fffffffffffffffLL) != 0)
+       rhx--;
+    }
   return (long double) (rhx - 1023);
 }
 #ifndef __logbl