Fix log2 (1) in round-downward mode (bug 17042).

As with other issues of this kind, bug 17042 is log2 (1) wrongly
returning -0 instead of +0 in round-downward mode because of
implementations effectively in terms of log1p (x - 1).  This patch
fixes the issue in the same way used for log and log10.

Tested x86_64 and x86 and ulps updated accordingly.  Also tested for
mips64 to confirm a fix was needed for ldbl-128 and to validate that
fix (also applied to ldbl-128ibm since that version of log2l is
essentially the same as the ldbl-128 one).

	[BZ #17042]
	* sysdeps/i386/fpu/e_log2.S (__ieee754_log2): Take absolete value
	when x - 1 is zero.
	* sysdeps/i386/fpu/e_log2f.S (__ieee754_log2f): Likewise.
	* sysdeps/i386/fpu/e_log2l.S (__ieee754_log2l): Likewise.
	* sysdeps/ieee754/ldbl-128/e_log2l.c (__ieee754_log2l): Return
	0.0L for an argument of 1.0L.
	* sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l):
	Likewise.
	* sysdeps/x86_64/fpu/e_log2l.S (__ieee754_log2l): Take absolute
	value when x - 1 is zero.
	* math/libm-test.inc (log2_test): Use ALL_RM_TEST.
	* sysdeps/i386/fpu/libm-test-ulps: Update.
	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
This commit is contained in:
Joseph Myers 2014-06-10 12:07:15 +00:00
parent 2c3520d98d
commit f8ba1b5654
11 changed files with 91 additions and 8 deletions

View File

@ -1,3 +1,20 @@
2014-06-10 Joseph Myers <joseph@codesourcery.com>
[BZ #17042]
* sysdeps/i386/fpu/e_log2.S (__ieee754_log2): Take absolete value
when x - 1 is zero.
* sysdeps/i386/fpu/e_log2f.S (__ieee754_log2f): Likewise.
* sysdeps/i386/fpu/e_log2l.S (__ieee754_log2l): Likewise.
* sysdeps/ieee754/ldbl-128/e_log2l.c (__ieee754_log2l): Return
0.0L for an argument of 1.0L.
* sysdeps/ieee754/ldbl-128ibm/e_log2l.c (__ieee754_log2l):
Likewise.
* sysdeps/x86_64/fpu/e_log2l.S (__ieee754_log2l): Take absolute
value when x - 1 is zero.
* math/libm-test.inc (log2_test): Use ALL_RM_TEST.
* sysdeps/i386/fpu/libm-test-ulps: Update.
* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.
2014-06-09 Bernard Ogden <bernie.ogden@linaro.org>
[BZ #15119]

2
NEWS
View File

@ -19,7 +19,7 @@ Version 2.20
16791, 16796, 16799, 16800, 16815, 16823, 16824, 16831, 16838, 16849,
16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16912, 16915,
16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16965, 16966,
16967, 16977, 16978, 16984, 16990, 17009.
16967, 16977, 16978, 16984, 16990, 17009, 17042.
* The minimum Linux kernel version that this version of the GNU C Library
can be used with is 2.6.32.

View File

@ -7840,9 +7840,7 @@ static const struct test_f_f_data log2_test_data[] =
static void
log2_test (void)
{
START (log2, 0);
RUN_TEST_LOOP_f_f (log2, log2_test_data, );
END;
ALL_RM_TEST (log2, 0, log2_test_data, RUN_TEST_LOOP_f_f, END);
}

View File

@ -47,7 +47,13 @@ ENTRY(__ieee754_log2)
fnstsw // x-1 : x : 1
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : 1
fxam
fnstsw
andb $0x45, %ah
cmpb $0x40, %ah
jne 5f
fabs // log2(1) is +0 in all rounding modes.
5: fstp %st(1) // x-1 : 1
fyl2xp1 // log(x)
ret

View File

@ -47,7 +47,13 @@ ENTRY(__ieee754_log2f)
fnstsw // x-1 : x : 1
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : 1
fxam
fnstsw
andb $0x45, %ah
cmpb $0x40, %ah
jne 5f
fabs // log2(1) is +0 in all rounding modes.
5: fstp %st(1) // x-1 : 1
fyl2xp1 // log(x)
ret

View File

@ -47,7 +47,13 @@ ENTRY(__ieee754_log2l)
fnstsw // x-1 : x : 1
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : 1
fxam
fnstsw
andb $0x45, %ah
cmpb $0x40, %ah
jne 5f
fabs // log2(1) is +0 in all rounding modes.
5: fstp %st(1) // x-1 : 1
fyl2xp1 // log(x)
ret

View File

@ -1588,6 +1588,22 @@ ifloat: 1
ildouble: 1
ldouble: 1
Function: "log2_towardzero":
double: 1
float: 1
idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
Function: "log2_upward":
double: 1
float: 1
idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
Function: "log_downward":
ildouble: 1
ldouble: 1

View File

@ -188,6 +188,9 @@ __ieee754_log2l (x)
if (hx >= 0x7fff000000000000LL)
return (x + x);
if (x == 1.0L)
return 0.0L;
/* separate mantissa from exponent */
/* Note, frexp is used so that denormal numbers

View File

@ -190,6 +190,9 @@ __ieee754_log2l (x)
if (hx >= 0x7ff0000000000000LL)
return (x + x);
if (x == 1.0L)
return 0.0L;
/* separate mantissa from exponent */
/* Note, frexp is used so that denormal numbers

View File

@ -45,7 +45,13 @@ ENTRY(__ieee754_log2l)
fnstsw // x-1 : x : 1
andb $0x45, %ah
jz 2f
fstp %st(1) // x-1 : 1
fxam
fnstsw
andb $0x45, %ah
cmpb $0x40, %ah
jne 5f
fabs // log2(1) is +0 in all rounding modes.
5: fstp %st(1) // x-1 : 1
fyl2xp1 // log(x)
ret

View File

@ -1665,6 +1665,28 @@ ifloat: 1
ildouble: 1
ldouble: 1
Function: "log2_downward":
double: 2
float: 2
idouble: 2
ifloat: 2
Function: "log2_towardzero":
double: 1
float: 1
idouble: 1
ifloat: 1
ildouble: 1
ldouble: 1
Function: "log2_upward":
double: 2
float: 2
idouble: 2
ifloat: 2
ildouble: 1
ldouble: 1
Function: "log_downward":
float: 1
ifloat: 1