Fix nearbyintf rounding.

This commit is contained in:
Joseph Myers 2012-02-22 13:03:40 +00:00
parent fe45ce09f3
commit 6cbeae4719
4 changed files with 35 additions and 16 deletions

View file

@ -1,3 +1,11 @@
2012-02-22 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.
2012-02-22 Joseph Myers <joseph@codesourcery.com>
[BZ #2548]

8
NEWS
View file

@ -9,10 +9,10 @@ Version 2.16
* The following bugs are resolved with this release:
174, 350, 411, 2548, 3335, 4026, 4596, 4822, 5077, 5805, 5993, 6884, 6907,
9739, 9902, 10110, 10140, 10210, 11174, 11322, 11494, 12047, 13058, 13525,
13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551,
13552, 13553, 13555, 13559, 13583, 13618, 13695, 13704
174, 350, 411, 2547, 2548, 3335, 4026, 4596, 4822, 5077, 5805, 5993, 6884,
6907, 9739, 9902, 10110, 10140, 10210, 11174, 11322, 11365, 11494, 12047,
13058, 13525, 13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533,
13547, 13551, 13552, 13553, 13555, 13559, 13583, 13618, 13695, 13704
* ISO C11 support:

View file

@ -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);
}

View file

@ -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];