1 |
|
|
/* k_rem_pio2f.c -- float version of k_rem_pio2.c |
2 |
|
|
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. |
3 |
|
|
*/ |
4 |
|
|
|
5 |
|
|
/* |
6 |
|
|
* ==================================================== |
7 |
|
|
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
8 |
|
|
* |
9 |
|
|
* Developed at SunPro, a Sun Microsystems, Inc. business. |
10 |
|
|
* Permission to use, copy, modify, and distribute this |
11 |
|
|
* software is freely granted, provided that this notice |
12 |
|
|
* is preserved. |
13 |
|
|
* ==================================================== |
14 |
|
|
*/ |
15 |
|
|
|
16 |
|
|
#include "math.h" |
17 |
|
|
#include "math_private.h" |
18 |
|
|
|
19 |
|
|
/* In the float version, the input parameter x contains 8 bit |
20 |
|
|
integers, not 24 bit integers. 113 bit precision is not supported. */ |
21 |
|
|
|
22 |
|
|
static const int init_jk[] = {4,7,9}; /* initial value for jk */ |
23 |
|
|
|
24 |
|
|
static const float PIo2[] = { |
25 |
|
|
1.5703125000e+00, /* 0x3fc90000 */ |
26 |
|
|
4.5776367188e-04, /* 0x39f00000 */ |
27 |
|
|
2.5987625122e-05, /* 0x37da0000 */ |
28 |
|
|
7.5437128544e-08, /* 0x33a20000 */ |
29 |
|
|
6.0026650317e-11, /* 0x2e840000 */ |
30 |
|
|
7.3896444519e-13, /* 0x2b500000 */ |
31 |
|
|
5.3845816694e-15, /* 0x27c20000 */ |
32 |
|
|
5.6378512969e-18, /* 0x22d00000 */ |
33 |
|
|
8.3009228831e-20, /* 0x1fc40000 */ |
34 |
|
|
3.2756352257e-22, /* 0x1bc60000 */ |
35 |
|
|
6.3331015649e-25, /* 0x17440000 */ |
36 |
|
|
}; |
37 |
|
|
|
38 |
|
|
static const float |
39 |
|
|
zero = 0.0, |
40 |
|
|
one = 1.0, |
41 |
|
|
two8 = 2.5600000000e+02, /* 0x43800000 */ |
42 |
|
|
twon8 = 3.9062500000e-03; /* 0x3b800000 */ |
43 |
|
|
|
44 |
|
|
int |
45 |
|
|
__kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, |
46 |
|
|
const int32_t *ipio2) |
47 |
|
|
{ |
48 |
|
|
int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; |
49 |
|
|
float z,fw,f[20],fq[20],q[20]; |
50 |
|
|
|
51 |
|
|
/* initialize jk*/ |
52 |
|
|
jk = init_jk[prec]; |
53 |
|
|
jp = jk; |
54 |
|
|
|
55 |
|
|
/* determine jx,jv,q0, note that 3>q0 */ |
56 |
|
|
jx = nx-1; |
57 |
|
|
jv = (e0-3)/8; if(jv<0) jv=0; |
58 |
|
|
q0 = e0-8*(jv+1); |
59 |
|
|
|
60 |
|
|
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ |
61 |
|
|
j = jv-jx; m = jx+jk; |
62 |
|
|
for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (float) ipio2[j]; |
63 |
|
|
|
64 |
|
|
/* compute q[0],q[1],...q[jk] */ |
65 |
|
|
for (i=0;i<=jk;i++) { |
66 |
|
|
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; |
67 |
|
|
} |
68 |
|
|
|
69 |
|
|
jz = jk; |
70 |
|
|
recompute: |
71 |
|
|
/* distill q[] into iq[] reversingly */ |
72 |
|
|
for(i=0,j=jz,z=q[jz];j>0;i++,j--) { |
73 |
|
|
fw = (float)((int32_t)(twon8* z)); |
74 |
|
|
iq[i] = (int32_t)(z-two8*fw); |
75 |
|
|
z = q[j-1]+fw; |
76 |
|
|
} |
77 |
|
|
|
78 |
|
|
/* compute n */ |
79 |
|
|
z = scalbnf(z,q0); /* actual value of z */ |
80 |
|
|
z -= (float)8.0*floorf(z*(float)0.125); /* trim off integer >= 8 */ |
81 |
|
|
n = (int32_t) z; |
82 |
|
|
z -= (float)n; |
83 |
|
|
ih = 0; |
84 |
|
|
if(q0>0) { /* need iq[jz-1] to determine n */ |
85 |
|
|
i = (iq[jz-1]>>(8-q0)); n += i; |
86 |
|
|
iq[jz-1] -= i<<(8-q0); |
87 |
|
|
ih = iq[jz-1]>>(7-q0); |
88 |
|
|
} |
89 |
|
|
else if(q0==0) ih = iq[jz-1]>>8; |
90 |
|
|
else if(z>=(float)0.5) ih=2; |
91 |
|
|
|
92 |
|
|
if(ih>0) { /* q > 0.5 */ |
93 |
|
|
n += 1; carry = 0; |
94 |
|
|
for(i=0;i<jz ;i++) { /* compute 1-q */ |
95 |
|
|
j = iq[i]; |
96 |
|
|
if(carry==0) { |
97 |
|
|
if(j!=0) { |
98 |
|
|
carry = 1; iq[i] = 0x100- j; |
99 |
|
|
} |
100 |
|
|
} else iq[i] = 0xff - j; |
101 |
|
|
} |
102 |
|
|
if(q0>0) { /* rare case: chance is 1 in 12 */ |
103 |
|
|
switch(q0) { |
104 |
|
|
case 1: |
105 |
|
|
iq[jz-1] &= 0x7f; break; |
106 |
|
|
case 2: |
107 |
|
|
iq[jz-1] &= 0x3f; break; |
108 |
|
|
} |
109 |
|
|
} |
110 |
|
|
if(ih==2) { |
111 |
|
|
z = one - z; |
112 |
|
|
if(carry!=0) z -= scalbnf(one,q0); |
113 |
|
|
} |
114 |
|
|
} |
115 |
|
|
|
116 |
|
|
/* check if recomputation is needed */ |
117 |
|
|
if(z==zero) { |
118 |
|
|
j = 0; |
119 |
|
|
for (i=jz-1;i>=jk;i--) j |= iq[i]; |
120 |
|
|
if(j==0) { /* need recomputation */ |
121 |
|
|
for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ |
122 |
|
|
|
123 |
|
|
for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ |
124 |
|
|
f[jx+i] = (float) ipio2[jv+i]; |
125 |
|
|
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; |
126 |
|
|
q[i] = fw; |
127 |
|
|
} |
128 |
|
|
jz += k; |
129 |
|
|
goto recompute; |
130 |
|
|
} |
131 |
|
|
} |
132 |
|
|
|
133 |
|
|
/* chop off zero terms */ |
134 |
|
|
if(z==(float)0.0) { |
135 |
|
|
jz -= 1; q0 -= 8; |
136 |
|
|
while(iq[jz]==0) { jz--; q0-=8;} |
137 |
|
|
} else { /* break z into 8-bit if necessary */ |
138 |
|
|
z = scalbnf(z,-q0); |
139 |
|
|
if(z>=two8) { |
140 |
|
|
fw = (float)((int32_t)(twon8*z)); |
141 |
|
|
iq[jz] = (int32_t)(z-two8*fw); |
142 |
|
|
jz += 1; q0 += 8; |
143 |
|
|
iq[jz] = (int32_t) fw; |
144 |
|
|
} else iq[jz] = (int32_t) z ; |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
/* convert integer "bit" chunk to floating-point value */ |
148 |
|
|
fw = scalbnf(one,q0); |
149 |
|
|
for(i=jz;i>=0;i--) { |
150 |
|
|
q[i] = fw*(float)iq[i]; fw*=twon8; |
151 |
|
|
} |
152 |
|
|
|
153 |
|
|
/* compute PIo2[0,...,jp]*q[jz,...,0] */ |
154 |
|
|
for(i=jz;i>=0;i--) { |
155 |
|
|
for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; |
156 |
|
|
fq[jz-i] = fw; |
157 |
|
|
} |
158 |
|
|
|
159 |
|
|
/* compress fq[] into y[] */ |
160 |
|
|
switch(prec) { |
161 |
|
|
case 0: |
162 |
|
|
fw = 0.0; |
163 |
|
|
for (i=jz;i>=0;i--) fw += fq[i]; |
164 |
|
|
y[0] = (ih==0)? fw: -fw; |
165 |
|
|
break; |
166 |
|
|
case 1: |
167 |
|
|
case 2: |
168 |
|
|
fw = 0.0; |
169 |
|
|
for (i=jz;i>=0;i--) fw += fq[i]; |
170 |
|
|
y[0] = (ih==0)? fw: -fw; |
171 |
|
|
fw = fq[0]-fw; |
172 |
|
|
for (i=1;i<=jz;i++) fw += fq[i]; |
173 |
|
|
y[1] = (ih==0)? fw: -fw; |
174 |
|
|
break; |
175 |
|
|
case 3: /* painful */ |
176 |
|
|
for (i=jz;i>0;i--) { |
177 |
|
|
fw = fq[i-1]+fq[i]; |
178 |
|
|
fq[i] += fq[i-1]-fw; |
179 |
|
|
fq[i-1] = fw; |
180 |
|
|
} |
181 |
|
|
for (i=jz;i>1;i--) { |
182 |
|
|
fw = fq[i-1]+fq[i]; |
183 |
|
|
fq[i] += fq[i-1]-fw; |
184 |
|
|
fq[i-1] = fw; |
185 |
|
|
} |
186 |
|
|
for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; |
187 |
|
|
if(ih==0) { |
188 |
|
|
y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; |
189 |
|
|
} else { |
190 |
|
|
y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; |
191 |
|
|
} |
192 |
|
|
} |
193 |
|
|
return n&7; |
194 |
|
|
} |