1 #include <math.h> 2 #include <errno.h> 3 4 /* modf suitable for IEEE double-precision */ 5 6 #define MASK 0x7ffL 7 #define SIGN 0x80000000 8 #define SHIFT 20 9 #define BIAS 1022L 10 11 typedef union 12 { 13 double d; 14 struct 15 { 16 long ms; 17 long ls; 18 } i; 19 } Cheat; 20 21 double modf(double d,double * ip)22modf(double d, double *ip) 23 { 24 Cheat x; 25 int e; 26 27 if(-1 < d && d < 1) { 28 *ip = 0; 29 return d; 30 } 31 x.d = d; 32 x.i.ms &= ~SIGN; 33 e = (x.i.ms >> SHIFT) & MASK; 34 if(e == MASK || e == 0){ 35 errno = EDOM; 36 *ip = (d > 0)? HUGE_VAL : -HUGE_VAL; 37 return 0; 38 } 39 e -= BIAS; 40 if(e <= SHIFT+1) { 41 x.i.ms &= ~(0x1fffffL >> e); 42 x.i.ls = 0; 43 } else 44 if(e <= SHIFT+33) 45 x.i.ls &= ~(0x7fffffffL >> (e-SHIFT-2)); 46 if(d > 0){ 47 *ip = x.d; 48 return d - x.d; 49 }else{ 50 *ip = -x.d; 51 return d + x.d; 52 } 53 } 54