This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix nearbyintf rounding (bugs 2547, 11365)


The nearbyintf implementation is substantially the same as rintf (the
only difference being that nearbyintf does not raise the "inexact"
exception, so there are feholdexcept/fesetenv pairs).  So it has the
same bugs, and much the same fix as in
<http://sourceware.org/ml/libc-alpha/2012-02/msg00397.html> applies.
This fix adds both the tests added for rint and the specific testcases
from the bug reports for nearbyint.

2012-02-19  Joseph Myers  <joseph@codesourcery.com>

	[BZ #2547]
	[BZ #11365]
	* sysdeps/ieee754/flt-32/s_nearbyintf.c (__nearbyintf): Do not
	manipulate bits before adding and subtracting TWO23[sx].
	* math/libm-test.inc (nearbyint_test): Add more tests.

diff --git a/math/libm-test.inc b/math/libm-test.inc
index 6243e1e..d904543 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -4632,6 +4632,29 @@ nearbyint_test (void)
   TEST_f_f (nearbyint, 524286.75, 524287.0);
   TEST_f_f (nearbyint, 524288.75, 524289.0);
 
+  TEST_f_f (nearbyint, 1048576.75, 1048577.0);
+  TEST_f_f (nearbyint, 2097152.75, 2097153.0);
+  TEST_f_f (nearbyint, 2492472.75, 2492473.0);
+  TEST_f_f (nearbyint, 2886220.75, 2886221.0);
+  TEST_f_f (nearbyint, 3058792.75, 3058793.0);
+  TEST_f_f (nearbyint, -1048576.75, -1048577.0);
+  TEST_f_f (nearbyint, -2097152.75, -2097153.0);
+  TEST_f_f (nearbyint, -2492472.75, -2492473.0);
+  TEST_f_f (nearbyint, -2886220.75, -2886221.0);
+  TEST_f_f (nearbyint, -3058792.75, -3058793.0);
+#ifndef TEST_FLOAT
+  TEST_f_f (nearbyint, 70368744177664.75, 70368744177665.0);
+  TEST_f_f (nearbyint, 140737488355328.75, 140737488355329.0);
+  TEST_f_f (nearbyint, 281474976710656.75, 281474976710657.0);
+  TEST_f_f (nearbyint, 562949953421312.75, 562949953421313.0);
+  TEST_f_f (nearbyint, 1125899906842624.75, 1125899906842625.0);
+  TEST_f_f (nearbyint, -70368744177664.75, -70368744177665.0);
+  TEST_f_f (nearbyint, -140737488355328.75, -140737488355329.0);
+  TEST_f_f (nearbyint, -281474976710656.75, -281474976710657.0);
+  TEST_f_f (nearbyint, -562949953421312.75, -562949953421313.0);
+  TEST_f_f (nearbyint, -1125899906842624.75, -1125899906842625.0);
+#endif
+
   END (nearbyint);
 }
 
diff --git a/sysdeps/ieee754/flt-32/s_nearbyintf.c b/sysdeps/ieee754/flt-32/s_nearbyintf.c
index 04ef9ab..a6d602b 100644
--- a/sysdeps/ieee754/flt-32/s_nearbyintf.c
+++ b/sysdeps/ieee754/flt-32/s_nearbyintf.c
@@ -30,18 +30,12 @@ __nearbyintf(float x)
 {
 	fenv_t env;
 	int32_t i0,j0,sx;
-	u_int32_t i,i1;
 	float w,t;
 	GET_FLOAT_WORD(i0,x);
 	sx = (i0>>31)&1;
 	j0 = ((i0>>23)&0xff)-0x7f;
 	if(j0<23) {
 	    if(j0<0) {
-		if((i0&0x7fffffff)==0) return x;
-		i1 = (i0&0x07fffff);
-		i0 &= 0xfff00000;
-		i0 |= ((i1|-i1)>>9)&0x400000;
-		SET_FLOAT_WORD(x,i0);
 		libc_feholdexceptf (&env);
 		w = TWO23[sx]+x;
 		t =  w-TWO23[sx];
@@ -49,17 +43,11 @@ __nearbyintf(float x)
 		GET_FLOAT_WORD(i0,t);
 		SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
 		return t;
-	    } else {
-		i = (0x007fffff)>>j0;
-		if((i0&i)==0) return x; /* x is integral */
-		i>>=1;
-		if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
 	    }
 	} else {
 	    if(__builtin_expect(j0==0x80, 0)) return x+x;	/* inf or NaN */
 	    else return x;		/* x is integral */
 	}
-	SET_FLOAT_WORD(x,i0);
 	libc_feholdexceptf (&env);
 	w = TWO23[sx]+x;
 	t = w-TWO23[sx];

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]