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 MASK 0x7ffL
|
||||||
#define SHIFT 20
|
#define SHIFT 20
|
||||||
#define BIAS 1022L
|
#define BIAS 1022L
|
||||||
|
#define SIG 52
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
|
@ -25,13 +26,18 @@ typedef union
|
||||||
double
|
double
|
||||||
frexp(double d, int *ep)
|
frexp(double d, int *ep)
|
||||||
{
|
{
|
||||||
Cheat x;
|
Cheat x, a;
|
||||||
|
|
||||||
if(d == 0) {
|
*ep = 0;
|
||||||
*ep = 0;
|
/* order matters: only isNaN can operate on NaN */
|
||||||
return 0;
|
if(isNaN(d) || isInf(d, 0) || d == 0)
|
||||||
}
|
return d;
|
||||||
x.d = 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;
|
*ep = ((x.ms >> SHIFT) & MASK) - BIAS;
|
||||||
x.ms &= ~(MASK << SHIFT);
|
x.ms &= ~(MASK << SHIFT);
|
||||||
x.ms |= BIAS << SHIFT;
|
x.ms |= BIAS << SHIFT;
|
||||||
|
|
|
@ -9,18 +9,24 @@
|
||||||
#define MASK 0x7ffL
|
#define MASK 0x7ffL
|
||||||
#define SHIFT 20
|
#define SHIFT 20
|
||||||
#define BIAS 1022L
|
#define BIAS 1022L
|
||||||
|
#define SIG 52
|
||||||
|
|
||||||
double
|
double
|
||||||
frexp(double d, int *ep)
|
frexp(double d, int *ep)
|
||||||
{
|
{
|
||||||
FPdbleword x;
|
FPdbleword x, a;
|
||||||
|
|
||||||
if(d == 0) {
|
*ep = 0;
|
||||||
*ep = 0;
|
/* order matters: only isNaN can operate on NaN */
|
||||||
return 0;
|
if(isNaN(d) || isInf(d, 0) || d == 0)
|
||||||
}
|
return d;
|
||||||
x.x = 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 &= ~(MASK << SHIFT);
|
||||||
x.hi |= BIAS << SHIFT;
|
x.hi |= BIAS << SHIFT;
|
||||||
return x.x;
|
return x.x;
|
||||||
|
|
Loading…
Reference in a new issue