1:
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: 14: 15: 16: 17:
18:
19: #include "math.h"
20: #include "math_private.h"
21:
22: static const int32_t npio2_hw[] = {
23: 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
24: 0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
25: 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
26: 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
27: 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
28: 0x404858EB, 0x404921FB,
29: };
30:
31: 32: 33: 34: 35: 36: 37: 38: 39:
40:
41: static const double
42: zero = 0.00000000000000000000e+00,
43: half = 5.00000000000000000000e-01,
44: two24 = 1.67772160000000000000e+07,
45: invpio2 = 6.36619772367581382433e-01,
46: pio2_1 = 1.57079632673412561417e+00,
47: pio2_1t = 6.07710050650619224932e-11,
48: pio2_2 = 6.07710050630396597660e-11,
49: pio2_2t = 2.02226624879595063154e-21,
50: pio2_3 = 2.02226624871116645580e-21,
51: pio2_3t = 8.47842766036889956997e-32;
52:
53: int32_t
54: __ieee754_rem_pio2(double x, double *y)
55: {
56: double z,w,t,r,fn;
57: double tx[3];
58: int32_t e0,i,j,nx,n,ix,hx;
59: u_int32_t low;
60:
61: GET_HIGH_WORD(hx,x);
62: ix = hx&0x7fffffff;
63: if(ix<=0x3fe921fb)
64: {y[0] = x; y[1] = 0; return 0;}
65: if(ix<0x4002d97c) {
66: if(hx>0) {
67: z = x - pio2_1;
68: if(ix!=0x3ff921fb) {
69: y[0] = z - pio2_1t;
70: y[1] = (z-y[0])-pio2_1t;
71: } else {
72: z -= pio2_2;
73: y[0] = z - pio2_2t;
74: y[1] = (z-y[0])-pio2_2t;
75: }
76: return 1;
77: } else {
78: z = x + pio2_1;
79: if(ix!=0x3ff921fb) {
80: y[0] = z + pio2_1t;
81: y[1] = (z-y[0])+pio2_1t;
82: } else {
83: z += pio2_2;
84: y[0] = z + pio2_2t;
85: y[1] = (z-y[0])+pio2_2t;
86: }
87: return -1;
88: }
89: }
90: if(ix<=0x413921fb) {
91: t = fabs(x);
92: n = (int32_t) (t*invpio2+half);
93: fn = (double)n;
94: r = t-fn*pio2_1;
95: w = fn*pio2_1t;
96: if(n<32&&ix!=npio2_hw[n-1]) {
97: y[0] = r-w;
98: } else {
99: u_int32_t high;
100: j = ix>>20;
101: y[0] = r-w;
102: GET_HIGH_WORD(high,y[0]);
103: i = j-((high>>20)&0x7ff);
104: if(i>16) {
105: t = r;
106: w = fn*pio2_2;
107: r = t-w;
108: w = fn*pio2_2t-((t-r)-w);
109: y[0] = r-w;
110: GET_HIGH_WORD(high,y[0]);
111: i = j-((high>>20)&0x7ff);
112: if(i>49) {
113: t = r;
114: w = fn*pio2_3;
115: r = t-w;
116: w = fn*pio2_3t-((t-r)-w);
117: y[0] = r-w;
118: }
119: }
120: }
121: y[1] = (r-y[0])-w;
122: if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
123: else return n;
124: }
125: 126: 127:
128: if(ix>=0x7ff00000) {
129: y[0]=y[1]=x-x; return 0;
130: }
131:
132: GET_LOW_WORD(low,x);
133: SET_LOW_WORD(z,low);
134: e0 = (ix>>20)-1046;
135: SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20)));
136: for(i=0;i<2;i++) {
137: tx[i] = (double)((int32_t)(z));
138: z = (z-tx[i])*two24;
139: }
140: tx[2] = z;
141: nx = 3;
142: while(tx[nx-1]==zero) nx--;
143: n = __kernel_rem_pio2(tx,y,e0,nx,2);
144: if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
145: return n;
146: }