summaryrefslogtreecommitdiffstats
path: root/newlib/libm/common/sf_scalbn.c
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2001-04-04 13:33:01 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2001-04-04 13:33:01 +0000
commit16740220a22d09a1c63714d93f1efc5fbe3927f3 (patch)
tree7b24242b9b20a0ee328c94acd2c95e1a8778c944 /newlib/libm/common/sf_scalbn.c
parent51fc3813e9a9ef8079b2fbde1b12647dd3f4ac93 (diff)
downloadcygnal-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.c22
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;