kf_rem_pio2.c 5.4 KB

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