1 #include <u.h> 2 #include <libc.h> 3 4 #define MASK 0x7ffL 5 #define SHIFT 20 6 #define BIAS 1022L 7 8 typedef union 9 { 10 double d; 11 struct 12 { 13 long ms; 14 long ls; 15 }; 16 } Cheat; 17 18 double 19 frexp(double d, int *ep) 20 { 21 Cheat x; 22 23 if(d == 0) { 24 *ep = 0; 25 return 0; 26 } 27 x.d = d; 28 *ep = ((x.ms >> SHIFT) & MASK) - BIAS; 29 x.ms &= ~(MASK << SHIFT); 30 x.ms |= BIAS << SHIFT; 31 return x.d; 32 } 33 34 double 35 ldexp(double d, int e) 36 { 37 Cheat x; 38 39 if(d == 0) 40 return 0; 41 x.d = d; 42 e += (x.ms >> SHIFT) & MASK; 43 if(e <= 0) 44 return 0; /* underflow */ 45 if(e >= MASK){ /* overflow */ 46 if(d < 0) 47 return Inf(-1); 48 return Inf(1); 49 } 50 x.ms &= ~(MASK << SHIFT); 51 x.ms |= (long)e << SHIFT; 52 return x.d; 53 } 54 55 double 56 modf(double d, double *ip) 57 { 58 Cheat x; 59 int e; 60 61 if(d < 1) { 62 if(d < 0) { 63 x.d = modf(-d, ip); 64 *ip = -*ip; 65 return -x.d; 66 } 67 *ip = 0; 68 return d; 69 } 70 x.d = d; 71 e = ((x.ms >> SHIFT) & MASK) - BIAS; 72 if(e <= SHIFT+1) { 73 x.ms &= ~(0x1fffffL >> e); 74 x.ls = 0; 75 } else 76 if(e <= SHIFT+33) 77 x.ls &= ~(0x7fffffffL >> (e-SHIFT-2)); 78 *ip = x.d; 79 return d - x.d; 80 } 81