#include <9pm/u.h>
#include <9pm/libc.h>
#define MASK 0x7ffL
#define SHIFT (64-11-1)
#define BIAS 1022L
double
frexp(double d, int *ep)
{
uvlong x;
if(d == 0) {
*ep = 0;
return 0;
}
x = *(uvlong*)&d;
*ep = (int)((x >> SHIFT) & MASK) - BIAS;
x &= ~((uvlong)MASK << SHIFT);
x |= (uvlong)BIAS << SHIFT;
return *(double*)&x;
}
double
ldexp(double d, int e)
{
uvlong x;
if(d == 0)
return 0;
x = *(uvlong*)&d;
e += (int)(x >> SHIFT) & MASK;
if(e <= 0)
return 0; /* underflow */
if(e >= MASK){ /* overflow */
if(d < 0)
return Inf(-1);
return Inf(1);
}
x &= ~((uvlong)MASK << SHIFT);
x |= (uvlong)e << SHIFT;
return *(double*)&x;
}
double
modf(double d, double *ip)
{
double dd;
uvlong x;
int e;
if(d < 1) {
if(d < 0) {
d = modf(-d, ip);
*ip = -*ip;
return -d;
}
*ip = 0;
return d;
}
x = *(uvlong*)&d;
e = (int)((x >> SHIFT) & MASK) - BIAS;
/*
* Keep the top 11+e bits; clear the rest.
*/
if(e <= 64-11)
x &= ~((uvlong)1 << (64-11-e))-1;
dd = *(double*)&x;
*ip = dd;
return d - dd;
}
syntax highlighted by Code2HTML, v. 0.9.1