diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-05-01 16:44:04 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-05-01 16:44:04 +0200 |
commit | decade55c63a802e288beb718de5d6b3cb81b0cc (patch) | |
tree | f0b35b949fd69da8fe3ff423f874ab4f08f4b682 /sys/src/libc | |
parent | 27f65a138abeee6accd3924f3e2c760b45c0b6ec (diff) |
frexp: handle NaN values (from sources)
Diffstat (limited to 'sys/src/libc')
-rw-r--r-- | sys/src/libc/port/frexp.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/src/libc/port/frexp.c b/sys/src/libc/port/frexp.c index 7809bd151..669f12152 100644 --- a/sys/src/libc/port/frexp.c +++ b/sys/src/libc/port/frexp.c @@ -9,18 +9,24 @@ #define MASK 0x7ffL #define SHIFT 20 #define BIAS 1022L +#define SIG 52 double frexp(double d, int *ep) { - FPdbleword x; + FPdbleword x, a; - if(d == 0) { - *ep = 0; - return 0; - } + *ep = 0; + /* order matters: only isNaN can operate on NaN */ + if(isNaN(d) || isInf(d, 0) || d == 0) + return d; x.x = d; - *ep = ((x.hi >> SHIFT) & MASK) - BIAS; + a.x = fabs(d); + if((a.hi >> SHIFT) == 0){ /* normalize subnormal numbers */ + x.x = (double)(1ULL<<SIG) * d; + *ep = -SIG; + } + *ep += ((x.hi >> SHIFT) & MASK) - BIAS; x.hi &= ~(MASK << SHIFT); x.hi |= BIAS << SHIFT; return x.x; |