summaryrefslogtreecommitdiffstats
path: root/lib/msun/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/msun/src')
-rw-r--r--lib/msun/src/s_rintf.c33
1 files changed, 7 insertions, 26 deletions
diff --git a/lib/msun/src/s_rintf.c b/lib/msun/src/s_rintf.c
index 591bbe9..429eac7 100644
--- a/lib/msun/src/s_rintf.c
+++ b/lib/msun/src/s_rintf.c
@@ -17,16 +17,11 @@
static char rcsid[] = "$FreeBSD$";
#endif
+#include <sys/types.h>
#include "math.h"
#include "math_private.h"
-/*
- * TWO23 is double instead of float to avoid a bug in gcc. Without
- * this, gcc thinks that TWO23[sx]+x and w-TWO23[sx] already have float
- * precision and doesn't clip them to float precision when they are
- * assigned and returned.
- */
-static const double
+static const float
TWO23[2]={
8.3886080000e+06, /* 0x4b000000 */
-8.3886080000e+06, /* 0xcb000000 */
@@ -36,34 +31,20 @@ float
rintf(float x)
{
int32_t i0,j0,sx;
- u_int32_t i,i1;
- float w,t;
+ volatile float w,t; /* volatile works around gcc bug */
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);
w = TWO23[sx]+x;
t = w-TWO23[sx];
- 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(j0==0x80) return x+x; /* inf or NaN */
- else return x; /* x is integral */
+ w = TWO23[sx]+x;
+ return w-TWO23[sx];
}
- SET_FLOAT_WORD(x,i0);
- w = TWO23[sx]+x;
- return w-TWO23[sx];
+ if(j0==0x80) return x+x; /* inf or NaN */
+ else return x; /* x is integral */
}
OpenPOWER on IntegriCloud