frexp: handle NaN values (from sources)
This commit is contained in:
parent
27f65a138a
commit
decade55c6
2 changed files with 23 additions and 11 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue