From: Joseph Myers Date: Thu, 26 Feb 2015 15:13:22 +0000 (+0000) Subject: Fix ldbl-128ibm logbl near powers of 2 (bug 18030). X-Git-Tag: glibc-2.22~540 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=380bd0fd2418f8988217de950f8b8ff18af0cb2b;p=thirdparty%2Fglibc.git Fix ldbl-128ibm logbl near powers of 2 (bug 18030). 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. --- diff --git a/ChangeLog b/ChangeLog index 90c42c85a36..ac6110b9659 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2015-02-26 Joseph Myers + + [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 [BZ #18032] diff --git a/NEWS b/NEWS index 77e081464d5..f09ffb1ccd8 100644 --- 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 diff --git a/math/libm-test.inc b/math/libm-test.inc index 6045764fd37..7acd29bc136 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -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 diff --git a/sysdeps/ieee754/ldbl-128ibm/s_logbl.c b/sysdeps/ieee754/ldbl-128ibm/s_logbl.c index dbd3478e633..22e5fc24c05 100644 --- a/sysdeps/ieee754/ldbl-128ibm/s_logbl.c +++ b/sysdeps/ieee754/ldbl-128ibm/s_logbl.c @@ -26,11 +26,12 @@ 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