summaryrefslogtreecommitdiffstats
path: root/lib/msun/src/s_rint.c
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>2005-12-03 07:38:35 +0000
committerbde <bde@FreeBSD.org>2005-12-03 07:38:35 +0000
commit7aaf0755d7de77c7044d1b1d0bac2dc4d57a5ead (patch)
tree1009ca5e1b2fffe19f88b347297c125a58f00e30 /lib/msun/src/s_rint.c
parent2e834acd9c22a16214cd4778d549130f052dee8b (diff)
downloadFreeBSD-src-7aaf0755d7de77c7044d1b1d0bac2dc4d57a5ead.zip
FreeBSD-src-7aaf0755d7de77c7044d1b1d0bac2dc4d57a5ead.tar.gz
Simplified the fix in rev.1.3. Instead of using long double for
TWO52[sx] to trick gcc into correctly converting TWO52[sx]+x to double on assignment to "double w", force a correct assignment by assigning to *(double *)&w. This is cleaner and avoids the double rounding problem on machines that evaluate double expressions in double precision. It is not necessary to convert w-TWO52[sx] to double precision on return as implied in the comment in rev.1.3, since the difference is exact.
Diffstat (limited to 'lib/msun/src/s_rint.c')
-rw-r--r--lib/msun/src/s_rint.c10
1 files changed, 2 insertions, 8 deletions
diff --git a/lib/msun/src/s_rint.c b/lib/msun/src/s_rint.c
index 2d9b672..0a7bfc4 100644
--- a/lib/msun/src/s_rint.c
+++ b/lib/msun/src/s_rint.c
@@ -27,13 +27,7 @@ static char rcsid[] = "$FreeBSD$";
#include "math.h"
#include "math_private.h"
-/*
- * TWO23 is long double instead of double to avoid a bug in gcc. Without
- * this, gcc thinks that TWO23[sx]+x and w-TWO23[sx] already have double
- * precision and doesn't clip them to double precision when they are
- * assigned and returned.
- */
-static const long double
+static const double
TWO52[2]={
4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
-4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
@@ -88,6 +82,6 @@ rint(double x)
if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
}
INSERT_WORDS(x,i0,i1);
- w = TWO52[sx]+x;
+ *(volatile double *)&w = TWO52[sx]+x; /* clip any extra precision */
return w-TWO52[sx];
}
OpenPOWER on IntegriCloud