summaryrefslogtreecommitdiff
path: root/sys/src/ape
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/ape
parent27f65a138abeee6accd3924f3e2c760b45c0b6ec (diff)
frexp: handle NaN values (from sources)
Diffstat (limited to 'sys/src/ape')
-rw-r--r--sys/src/ape/lib/ap/plan9/frexp.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/src/ape/lib/ap/plan9/frexp.c b/sys/src/ape/lib/ap/plan9/frexp.c
index 588f90cee..0d81f52c7 100644
--- a/sys/src/ape/lib/ap/plan9/frexp.c
+++ b/sys/src/ape/lib/ap/plan9/frexp.c
@@ -6,6 +6,7 @@
#define MASK 0x7ffL
#define SHIFT 20
#define BIAS 1022L
+#define SIG 52
typedef union
{
@@ -25,13 +26,18 @@ typedef union
double
frexp(double d, int *ep)
{
- Cheat x;
+ Cheat 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.d = d;
+ a.d = fabs(d);
+ if((a.ms >> SHIFT) == 0){ /* normalize subnormal numbers */
+ x.d = (double)(1ULL<<SIG) * d;
+ *ep = -SIG;
+ }
*ep = ((x.ms >> SHIFT) & MASK) - BIAS;
x.ms &= ~(MASK << SHIFT);
x.ms |= BIAS << SHIFT;