about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2017-03-15 22:00:54 +0000
committerJoseph Myers <joseph@codesourcery.com>2017-03-15 22:00:54 +0000
commite4e52ff059f46472145433d2bd003d5383f89e82 (patch)
treec5044e3b2e2f98778087319e79d308bd817e9a75 /sysdeps
parent5d20a49aaccef5ef7adac93d5ca159f6b7ba0105 (diff)
downloadglibc-e4e52ff059f46472145433d2bd003d5383f89e82.tar.gz
glibc-e4e52ff059f46472145433d2bd003d5383f89e82.tar.xz
glibc-e4e52ff059f46472145433d2bd003d5383f89e82.zip
Improve float range reduction accuracy near pi/2 (bug 21094).
Bug 21094 reports 3ulp errors of cosf and tanf for certain arguments
near pi/2 arising from the use of an insufficiently accurate range
reduction.  (To be clear, this is a quality-of-implementation issue
relating to the apparent intent of those particular cosf and tanf
implementations; 3ulp is within the general glibc accuracy goals, so
not inherently a bug.)

This patch fixes that error by making a wider range of cases use the
existing more accurate range reduction for arguments close to pi/2.
The wider range of values is still narrow enough for the "z -=
pio2_2;" in the more accurate case to be exact, as the code expects.

Tested for x86_64, x86 and mips64; no ulps updates needed (but at
least on mips64, the larger ulps were seen if the tests were added
without the substantive fix).

	[BZ #21094]
	* sysdeps/ieee754/flt-32/e_rem_pio2f.c (__ieee754_rem_pio2f): Use
	24+24+24-bit pi for wider range of values around pi/2.
	* math/auto-libm-test-in: Add more tests of cos and tan.
	* math/auto-libm-test-out-cos: Regenerated.
	* math/auto-libm-test-out-tan: Likewise.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/ieee754/flt-32/e_rem_pio2f.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sysdeps/ieee754/flt-32/e_rem_pio2f.c b/sysdeps/ieee754/flt-32/e_rem_pio2f.c
index 0928373498..c4d28c8657 100644
--- a/sysdeps/ieee754/flt-32/e_rem_pio2f.c
+++ b/sysdeps/ieee754/flt-32/e_rem_pio2f.c
@@ -100,7 +100,7 @@ int32_t __ieee754_rem_pio2f(float x, float *y)
 	if(ix<0x4016cbe4) {  /* |x| < 3pi/4, special case with n=+-1 */
 	    if(hx>0) {
 		z = x - pio2_1;
-		if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+		if((ix&0xffffffc0)!=0x3fc90fc0) { /* 24+24 bit pi OK */
 		    y[0] = z - pio2_1t;
 		    y[1] = (z-y[0])-pio2_1t;
 		} else {		/* near pi/2, use 24+24+24 bit pi */
@@ -111,7 +111,7 @@ int32_t __ieee754_rem_pio2f(float x, float *y)
 		return 1;
 	    } else {	/* negative x */
 		z = x + pio2_1;
-		if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
+		if((ix&0xffffffc0)!=0x3fc90fc0) { /* 24+24 bit pi OK */
 		    y[0] = z + pio2_1t;
 		    y[1] = (z-y[0])+pio2_1t;
 		} else {		/* near pi/2, use 24+24+24 bit pi */