ref: 08edf42ecca657297a473382b4e22fc9c5330cfc
parent: e808e8db9555d8adcc6229d05db9b06d398aae83
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Wed May 1 12:44:04 EDT 2013
frexp: handle NaN values (from sources)
--- 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 @@
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;
--- 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;
--
⑨