ef_rem_pio2.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. /* ef_rem_pio2.c -- float version of e_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. */
  23. /* __ieee754_rem_pio2f(x,y)
  24. *
  25. * return the remainder of x rem pi/2 in y[0]+y[1]
  26. * use __kernel_rem_pio2f()
  27. */
  28. #include "fdlibm.h"
  29. /*
  30. * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
  31. */
  32. #ifdef __STDC__
  33. static const __int32_t two_over_pi[] = {
  34. #else
  35. static __int32_t two_over_pi[] = {
  36. #endif
  37. 0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC,
  38. 0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62,
  39. 0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63,
  40. 0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A,
  41. 0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09,
  42. 0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29,
  43. 0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44,
  44. 0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41,
  45. 0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C,
  46. 0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8,
  47. 0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11,
  48. 0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF,
  49. 0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E,
  50. 0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5,
  51. 0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92,
  52. 0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08,
  53. 0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0,
  54. 0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3,
  55. 0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85,
  56. 0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80,
  57. 0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA,
  58. 0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B,
  59. };
  60. /* This array is like the one in e_rem_pio2.c, but the numbers are
  61. single precision and the last 8 bits are forced to 0. */
  62. #ifdef __STDC__
  63. static const __int32_t npio2_hw[] = {
  64. #else
  65. static __int32_t npio2_hw[] = {
  66. #endif
  67. 0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
  68. 0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
  69. 0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
  70. 0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
  71. 0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
  72. 0x4242c700, 0x42490f00
  73. };
  74. /*
  75. * invpio2: 24 bits of 2/pi
  76. * pio2_1: first 17 bit of pi/2
  77. * pio2_1t: pi/2 - pio2_1
  78. * pio2_2: second 17 bit of pi/2
  79. * pio2_2t: pi/2 - (pio2_1+pio2_2)
  80. * pio2_3: third 17 bit of pi/2
  81. * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
  82. */
  83. #ifdef __STDC__
  84. static const float
  85. #else
  86. static float
  87. #endif
  88. zero = 0.0000000000e+00, /* 0x00000000 */
  89. half = 5.0000000000e-01, /* 0x3f000000 */
  90. two8 = 2.5600000000e+02, /* 0x43800000 */
  91. invpio2 = 6.3661980629e-01, /* 0x3f22f984 */
  92. pio2_1 = 1.5707855225e+00, /* 0x3fc90f80 */
  93. pio2_1t = 1.0804334124e-05, /* 0x37354443 */
  94. pio2_2 = 1.0804273188e-05, /* 0x37354400 */
  95. pio2_2t = 6.0770999344e-11, /* 0x2e85a308 */
  96. pio2_3 = 6.0770943833e-11, /* 0x2e85a300 */
  97. pio2_3t = 6.1232342629e-17; /* 0x248d3132 */
  98. #ifdef __STDC__
  99. __int32_t __ieee754_rem_pio2f(float x, float *y)
  100. #else
  101. __int32_t __ieee754_rem_pio2f(x,y)
  102. float x,y[];
  103. #endif
  104. {
  105. float z,w,t,r,fn;
  106. float tx[3];
  107. __int32_t i,j,n,ix,hx;
  108. int e0,nx;
  109. GET_FLOAT_WORD(hx,x);
  110. ix = hx&0x7fffffff;
  111. if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */
  112. {y[0] = x; y[1] = 0; return 0;}
  113. if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
  114. if(hx>0) {
  115. z = x - pio2_1;
  116. if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
  117. y[0] = z - pio2_1t;
  118. y[1] = (z-y[0])-pio2_1t;
  119. } else { /* near pi/2, use 24+24+24 bit pi */
  120. z -= pio2_2;
  121. y[0] = z - pio2_2t;
  122. y[1] = (z-y[0])-pio2_2t;
  123. }
  124. return 1;
  125. } else { /* negative x */
  126. z = x + pio2_1;
  127. if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */
  128. y[0] = z + pio2_1t;
  129. y[1] = (z-y[0])+pio2_1t;
  130. } else { /* near pi/2, use 24+24+24 bit pi */
  131. z += pio2_2;
  132. y[0] = z + pio2_2t;
  133. y[1] = (z-y[0])+pio2_2t;
  134. }
  135. return -1;
  136. }
  137. }
  138. if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
  139. t = fabsf(x);
  140. n = (__int32_t) (t*invpio2+half);
  141. fn = (float)n;
  142. r = t-fn*pio2_1;
  143. w = fn*pio2_1t; /* 1st round good to 40 bit */
  144. if(n<32&&(ix&0xffffff00)!=npio2_hw[n-1]) {
  145. y[0] = r-w; /* quick check no cancellation */
  146. } else {
  147. __uint32_t high;
  148. j = ix>>23;
  149. y[0] = r-w;
  150. GET_FLOAT_WORD(high,y[0]);
  151. i = j-((high>>23)&0xff);
  152. if(i>8) { /* 2nd iteration needed, good to 57 */
  153. t = r;
  154. w = fn*pio2_2;
  155. r = t-w;
  156. w = fn*pio2_2t-((t-r)-w);
  157. y[0] = r-w;
  158. GET_FLOAT_WORD(high,y[0]);
  159. i = j-((high>>23)&0xff);
  160. if(i>25) { /* 3rd iteration need, 74 bits acc */
  161. t = r; /* will cover all possible cases */
  162. w = fn*pio2_3;
  163. r = t-w;
  164. w = fn*pio2_3t-((t-r)-w);
  165. y[0] = r-w;
  166. }
  167. }
  168. }
  169. y[1] = (r-y[0])-w;
  170. if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
  171. else return n;
  172. }
  173. /*
  174. * all other (large) arguments
  175. */
  176. if(!FLT_UWORD_IS_FINITE(ix)) {
  177. y[0]=y[1]=x-x; return 0;
  178. }
  179. /* set z = scalbn(|x|,ilogb(x)-7) */
  180. e0 = (int)((ix>>23)-134); /* e0 = ilogb(z)-7; */
  181. SET_FLOAT_WORD(z, ix - ((__int32_t)e0<<23));
  182. for(i=0;i<2;i++) {
  183. tx[i] = (float)((__int32_t)(z));
  184. z = (z-tx[i])*two8;
  185. }
  186. tx[2] = z;
  187. nx = 3;
  188. while(tx[nx-1]==zero) nx--; /* skip zero term */
  189. n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi);
  190. if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
  191. return n;
  192. }