1:
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19:
20:
21: #include <sys/cdefs.h>
22: #include <float.h>
23: #include <math.h>
24:
25: #include "math_private.h"
26:
27: static const double one = 1.0, Zero[] = {0.0, -0.0,};
28:
29: double
30: fmod(double x, double y)
31: {
32: int32_t n,hx,hy,hz,ix,iy,sx,i;
33: u_int32_t lx,ly,lz;
34:
35: EXTRACT_WORDS(hx,lx,x);
36: EXTRACT_WORDS(hy,ly,y);
37: sx = hx&0x80000000;
38: hx ^=sx;
39: hy &= 0x7fffffff;
40:
41:
42: if((hy|ly)==0||(hx>=0x7ff00000)||
43: ((hy|((ly|-ly)>>31))>0x7ff00000))
44: return (x*y)/(x*y);
45: if(hx<=hy) {
46: if((hx<hy)||(lx<ly)) return x;
47: if(lx==ly)
48: return Zero[(u_int32_t)sx>>31];
49: }
50:
51:
52: if(hx<0x00100000) {
53: if(hx==0) {
54: for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
55: } else {
56: for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
57: }
58: } else ix = (hx>>20)-1023;
59:
60:
61: if(hy<0x00100000) {
62: if(hy==0) {
63: for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
64: } else {
65: for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
66: }
67: } else iy = (hy>>20)-1023;
68:
69:
70: if(ix >= -1022)
71: hx = 0x00100000|(0x000fffff&hx);
72: else {
73: n = -1022-ix;
74: if(n<=31) {
75: hx = (hx<<n)|(lx>>(32-n));
76: lx <<= n;
77: } else {
78: hx = lx<<(n-32);
79: lx = 0;
80: }
81: }
82: if(iy >= -1022)
83: hy = 0x00100000|(0x000fffff&hy);
84: else {
85: n = -1022-iy;
86: if(n<=31) {
87: hy = (hy<<n)|(ly>>(32-n));
88: ly <<= n;
89: } else {
90: hy = ly<<(n-32);
91: ly = 0;
92: }
93: }
94:
95:
96: n = ix - iy;
97: while(n--) {
98: hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
99: if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
100: else {
101: if((hz|lz)==0)
102: return Zero[(u_int32_t)sx>>31];
103: hx = hz+hz+(lz>>31); lx = lz+lz;
104: }
105: }
106: hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
107: if(hz>=0) {hx=hz;lx=lz;}
108:
109:
110: if((hx|lx)==0)
111: return Zero[(u_int32_t)sx>>31];
112: while(hx<0x00100000) {
113: hx = hx+hx+(lx>>31); lx = lx+lx;
114: iy -= 1;
115: }
116: if(iy>= -1022) {
117: hx = ((hx-0x00100000)|((iy+1023)<<20));
118: INSERT_WORDS(x,hx|sx,lx);
119: } else {
120: n = -1022 - iy;
121: if(n<=20) {
122: lx = (lx>>n)|((u_int32_t)hx<<(32-n));
123: hx >>= n;
124: } else if (n<=31) {
125: lx = (hx<<(32-n))|(lx>>n); hx = sx;
126: } else {
127: lx = hx>>(n-32); hx = sx;
128: }
129: INSERT_WORDS(x,hx|sx,lx);
130: x *= one;
131: }
132: return x;
133: }
134:
135: #if LDBL_MANT_DIG == 53
136: #ifdef lint
137:
138: long double fmodl(long double, long double);
139: #else
140: __weak_alias(fmodl, fmod);
141: #endif
142: #endif