summaryrefslogtreecommitdiff
path: root/sys/src/libc
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-05-01 16:44:04 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-05-01 16:44:04 +0200
commitdecade55c63a802e288beb718de5d6b3cb81b0cc (patch)
treef0b35b949fd69da8fe3ff423f874ab4f08f4b682 /sys/src/libc
parent27f65a138abeee6accd3924f3e2c760b45c0b6ec (diff)
frexp: handle NaN values (from sources)
Diffstat (limited to 'sys/src/libc')
-rw-r--r--sys/src/libc/port/frexp.c18
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;