diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2001-04-04 13:33:01 +0000 |
---|---|---|
committer | Richard Sandiford <rdsandiford@googlemail.com> | 2001-04-04 13:33:01 +0000 |
commit | 16740220a22d09a1c63714d93f1efc5fbe3927f3 (patch) | |
tree | 7b24242b9b20a0ee328c94acd2c95e1a8778c944 /newlib/libm/common/sf_scalbn.c | |
parent | 51fc3813e9a9ef8079b2fbde1b12647dd3f4ac93 (diff) | |
download | cygnal-16740220a22d09a1c63714d93f1efc5fbe3927f3.tar.gz cygnal-16740220a22d09a1c63714d93f1efc5fbe3927f3.tar.bz2 cygnal-16740220a22d09a1c63714d93f1efc5fbe3927f3.zip |
* libc/include/machine/ieeefp.h: Comment about new configuration
macros _FLT_LARGEST_EXPONENT_IS_NORMAL and _FLT_NO_DENORMALS.
* libm/common/fdlib.h: Define new macros for testing floats.
* libm/common/sf_*: Use them.
* libm/math/ef_*: Likewise.
* libm/math/sf_*: Likewise.
Diffstat (limited to 'newlib/libm/common/sf_scalbn.c')
-rw-r--r-- | newlib/libm/common/sf_scalbn.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/newlib/libm/common/sf_scalbn.c b/newlib/libm/common/sf_scalbn.c index fb67c7816..700060010 100644 --- a/newlib/libm/common/sf_scalbn.c +++ b/newlib/libm/common/sf_scalbn.c @@ -15,6 +15,7 @@ #include "fdlibm.h" #include <limits.h> +#include <float.h> #if INT_MAX > 50000 #define OVERFLOW_INT 50000 @@ -40,25 +41,30 @@ tiny = 1.0e-30; #endif { __int32_t k,ix; + __uint32_t hx; + GET_FLOAT_WORD(ix,x); - k = (ix&0x7f800000)>>23; /* extract exponent */ - if (k==0) { /* 0 or subnormal x */ - if ((ix&0x7fffffff)==0) return x; /* +-0 */ + hx = ix&0x7fffffff; + k = hx>>23; /* extract exponent */ + if (FLT_UWORD_IS_ZERO(hx)) + return x; + if (!FLT_UWORD_IS_FINITE(hx)) + return x+x; /* NaN or Inf */ + if (FLT_UWORD_IS_SUBNORMAL(hx)) { x *= two25; GET_FLOAT_WORD(ix,x); k = ((ix&0x7f800000)>>23) - 25; if (n< -50000) return tiny*x; /*underflow*/ - } - if (k==0xff) return x+x; /* NaN or Inf */ + } k = k+n; - if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */ + if (k > FLT_LARGEST_EXP) return huge*copysignf(huge,x); /* overflow */ if (k > 0) /* normal result */ {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} - if (k <= -25) { + if (k < FLT_SMALLEST_EXP) { if (n > OVERFLOW_INT) /* in case integer overflow in n+k */ return huge*copysignf(huge,x); /*overflow*/ else return tiny*copysignf(tiny,x); /*underflow*/ - } + } k += 25; /* subnormal result */ SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x*twom25; |