#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; }