]> git.lizzy.rs Git - plan9front.git/blob - sys/src/ape/lib/ap/math/modf.c
ape: fix lockinit() for mips
[plan9front.git] / sys / src / ape / lib / ap / math / modf.c
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
22 modf(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 }