Numworks Epsilon  1.4.1
Graphing Calculator Operating System
k_rem_pio2f.c
Go to the documentation of this file.
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 }
#define floorf(x)
Definition: math.h:142
#define one
Definition: k_tan.c:68
int __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec, const int32_t *ipio2)
Definition: k_rem_pio2f.c:45
signed int int32_t
Definition: stdint.h:11
#define scalbnf(x, n)
Definition: math.h:155