mirror of
git://sourceware.org/git/glibc.git
synced 2025-04-06 14:10:30 +08:00
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.
This commit is contained in:
parent
4a28f4d55a
commit
380bd0fd24
@ -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]
|
||||
|
2
NEWS
2
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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user