diff options
author | das <das@FreeBSD.org> | 2005-03-07 04:55:58 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2005-03-07 04:55:58 +0000 |
commit | e1ac3a8c058a65b02d6664528411d6469e711412 (patch) | |
tree | f8c4ac60ad06be68b4ec26babec5d15e6075c461 /lib | |
parent | 4d2ad621bf42c8dfb26c6371162292b6d9077822 (diff) | |
download | FreeBSD-src-e1ac3a8c058a65b02d6664528411d6469e711412.zip FreeBSD-src-e1ac3a8c058a65b02d6664528411d6469e711412.tar.gz |
- Try harder to trick gcc into not optimizing away statements
that are intended to raise underflow and inexact exceptions.
- On systems where long double is the same as double, nextafter
should be aliased as nexttoward, nexttowardl, and nextafterl.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/msun/src/s_nextafter.c | 18 | ||||
-rw-r--r-- | lib/msun/src/s_nextafterf.c | 9 |
2 files changed, 19 insertions, 8 deletions
diff --git a/lib/msun/src/s_nextafter.c b/lib/msun/src/s_nextafter.c index 4fc5b77..a235099 100644 --- a/lib/msun/src/s_nextafter.c +++ b/lib/msun/src/s_nextafter.c @@ -21,12 +21,16 @@ static char rcsid[] = "$FreeBSD$"; * Special cases: */ +#include <sys/cdefs.h> +#include <float.h> + #include "math.h" #include "math_private.h" double nextafter(double x, double y) { + volatile double t; int32_t hx,hy,ix,iy; u_int32_t lx,ly; @@ -41,8 +45,8 @@ nextafter(double x, double y) if(x==y) return y; /* x=y, return y */ if((ix|lx)==0) { /* x == 0 */ INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ + t = x*x; + if(t==x) return t; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ @@ -64,8 +68,8 @@ nextafter(double x, double y) hy = hx&0x7ff00000; if(hy>=0x7ff00000) return x+x; /* overflow */ if(hy<0x00100000) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ + t = x*x; + if(t!=x) { /* raise underflow flag */ INSERT_WORDS(y,hx,lx); return y; } @@ -73,3 +77,9 @@ nextafter(double x, double y) INSERT_WORDS(x,hx,lx); return x; } + +#if (LDBL_MANT_DIG == 53) +__strong_reference(nextafter, nexttoward); +__strong_reference(nextafter, nexttowardl); +__strong_reference(nextafter, nextafterl); +#endif diff --git a/lib/msun/src/s_nextafterf.c b/lib/msun/src/s_nextafterf.c index c4032e9..b8a1125 100644 --- a/lib/msun/src/s_nextafterf.c +++ b/lib/msun/src/s_nextafterf.c @@ -23,6 +23,7 @@ static char rcsid[] = "$FreeBSD$"; float nextafterf(float x, float y) { + volatile float t; int32_t hx,hy,ix,iy; GET_FLOAT_WORD(hx,x); @@ -36,8 +37,8 @@ nextafterf(float x, float y) if(x==y) return y; /* x=y, return y */ if(ix==0) { /* x == 0 */ SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ + t = x*x; + if(t==x) return t; else return x; /* raise underflow flag */ } if(hx>=0) { /* x > 0 */ if(hx>hy) { /* x > y, x -= ulp */ @@ -55,8 +56,8 @@ nextafterf(float x, float y) hy = hx&0x7f800000; if(hy>=0x7f800000) return x+x; /* overflow */ if(hy<0x00800000) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ + t = x*x; + if(t!=x) { /* raise underflow flag */ SET_FLOAT_WORD(y,hx); return y; } |