This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Fix nearbyintf rounding (bugs 2547, 11365)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: libc-alpha at sourceware dot org
- Date: Mon, 20 Feb 2012 00:05:45 +0000 (UTC)
- Subject: 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