summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/plan9/frexp.c
diff options
context:
space:
mode:
authorppatience0 <ppatience0@gmail.com>2013-05-06 19:37:51 -0400
committerppatience0 <ppatience0@gmail.com>2013-05-06 19:37:51 -0400
commita1bc7c76ba7392960086e53132bbc5f358bd6b03 (patch)
tree64a3822652f2ff9eed722990175b7c036628242c /sys/src/ape/lib/ap/plan9/frexp.c
parent5ac6088b96c67e9799bc8009d46b72819521da87 (diff)
parentcd66b11f67654edfa54cab05422310d5c923784a (diff)
merge
Diffstat (limited to 'sys/src/ape/lib/ap/plan9/frexp.c')
-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;