sinf.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* sinf.c
  2. *
  3. * Circular sine
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float x, y, sinf();
  10. *
  11. * y = sinf( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Range reduction is into intervals of pi/4. The reduction
  18. * error is nearly eliminated by contriving an extended precision
  19. * modular arithmetic.
  20. *
  21. * Two polynomial approximating functions are employed.
  22. * Between 0 and pi/4 the sine is approximated by
  23. * x + x**3 P(x**2).
  24. * Between pi/4 and pi/2 the cosine is represented as
  25. * 1 - x**2 Q(x**2).
  26. *
  27. *
  28. * ACCURACY:
  29. *
  30. * Relative error:
  31. * arithmetic domain # trials peak rms
  32. * IEEE -4096,+4096 100,000 1.2e-7 3.0e-8
  33. * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8
  34. *
  35. * ERROR MESSAGES:
  36. *
  37. * message condition value returned
  38. * sin total loss x > 2^24 0.0
  39. *
  40. * Partial loss of accuracy begins to occur at x = 2^13
  41. * = 8192. Results may be meaningless for x >= 2^24
  42. * The routine as implemented flags a TLOSS error
  43. * for x >= 2^24 and returns 0.0.
  44. */
  45. /* cosf.c
  46. *
  47. * Circular cosine
  48. *
  49. *
  50. *
  51. * SYNOPSIS:
  52. *
  53. * float x, y, cosf();
  54. *
  55. * y = cosf( x );
  56. *
  57. *
  58. *
  59. * DESCRIPTION:
  60. *
  61. * Range reduction is into intervals of pi/4. The reduction
  62. * error is nearly eliminated by contriving an extended precision
  63. * modular arithmetic.
  64. *
  65. * Two polynomial approximating functions are employed.
  66. * Between 0 and pi/4 the cosine is approximated by
  67. * 1 - x**2 Q(x**2).
  68. * Between pi/4 and pi/2 the sine is represented as
  69. * x + x**3 P(x**2).
  70. *
  71. *
  72. * ACCURACY:
  73. *
  74. * Relative error:
  75. * arithmetic domain # trials peak rms
  76. * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8
  77. */
  78. /*
  79. Cephes Math Library Release 2.2: June, 1992
  80. Copyright 1985, 1987, 1988, 1992 by Stephen L. Moshier
  81. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  82. */
  83. /* Single precision circular sine
  84. * test interval: [-pi/4, +pi/4]
  85. * trials: 10000
  86. * peak relative error: 6.8e-8
  87. * rms relative error: 2.6e-8
  88. */
  89. #include <math.h>
  90. static float FOPI = 1.27323954473516;
  91. extern float PIO4F;
  92. /* Note, these constants are for a 32-bit significand: */
  93. /*
  94. static float DP1 = 0.7853851318359375;
  95. static float DP2 = 1.30315311253070831298828125e-5;
  96. static float DP3 = 3.03855025325309630e-11;
  97. static float lossth = 65536.;
  98. */
  99. /* These are for a 24-bit significand: */
  100. static float DP1 = 0.78515625;
  101. static float DP2 = 2.4187564849853515625e-4;
  102. static float DP3 = 3.77489497744594108e-8;
  103. static float lossth = 8192.;
  104. static float T24M1 = 16777215.;
  105. static float sincof[] = {
  106. -1.9515295891E-4,
  107. 8.3321608736E-3,
  108. -1.6666654611E-1
  109. };
  110. static float coscof[] = {
  111. 2.443315711809948E-005,
  112. -1.388731625493765E-003,
  113. 4.166664568298827E-002
  114. };
  115. float sinf( float xx )
  116. {
  117. float *p;
  118. float x, y, z;
  119. register unsigned long j;
  120. register int sign;
  121. sign = 1;
  122. x = xx;
  123. if( xx < 0 )
  124. {
  125. sign = -1;
  126. x = -xx;
  127. }
  128. if( x > T24M1 )
  129. {
  130. mtherr( "sinf", TLOSS );
  131. return(0.0);
  132. }
  133. j = FOPI * x; /* integer part of x/(PI/4) */
  134. y = j;
  135. /* map zeros to origin */
  136. if( j & 1 )
  137. {
  138. j += 1;
  139. y += 1.0;
  140. }
  141. j &= 7; /* octant modulo 360 degrees */
  142. /* reflect in x axis */
  143. if( j > 3)
  144. {
  145. sign = -sign;
  146. j -= 4;
  147. }
  148. if( x > lossth )
  149. {
  150. mtherr( "sinf", PLOSS );
  151. x = x - y * PIO4F;
  152. }
  153. else
  154. {
  155. /* Extended precision modular arithmetic */
  156. x = ((x - y * DP1) - y * DP2) - y * DP3;
  157. }
  158. /*einits();*/
  159. z = x * x;
  160. if( (j==1) || (j==2) )
  161. {
  162. /* measured relative error in +/- pi/4 is 7.8e-8 */
  163. /*
  164. y = (( 2.443315711809948E-005 * z
  165. - 1.388731625493765E-003) * z
  166. + 4.166664568298827E-002) * z * z;
  167. */
  168. p = coscof;
  169. y = *p++;
  170. y = y * z + *p++;
  171. y = y * z + *p++;
  172. y *= z * z;
  173. y -= 0.5 * z;
  174. y += 1.0;
  175. }
  176. else
  177. {
  178. /* Theoretical relative error = 3.8e-9 in [-pi/4, +pi/4] */
  179. /*
  180. y = ((-1.9515295891E-4 * z
  181. + 8.3321608736E-3) * z
  182. - 1.6666654611E-1) * z * x;
  183. y += x;
  184. */
  185. p = sincof;
  186. y = *p++;
  187. y = y * z + *p++;
  188. y = y * z + *p++;
  189. y *= z * x;
  190. y += x;
  191. }
  192. /*einitd();*/
  193. if(sign < 0)
  194. y = -y;
  195. return( y);
  196. }
  197. /* Single precision circular cosine
  198. * test interval: [-pi/4, +pi/4]
  199. * trials: 10000
  200. * peak relative error: 8.3e-8
  201. * rms relative error: 2.2e-8
  202. */
  203. float cosf( float xx )
  204. {
  205. float x, y, z;
  206. int j, sign;
  207. /* make argument positive */
  208. sign = 1;
  209. x = xx;
  210. if( x < 0 )
  211. x = -x;
  212. if( x > T24M1 )
  213. {
  214. mtherr( "cosf", TLOSS );
  215. return(0.0);
  216. }
  217. j = FOPI * x; /* integer part of x/PIO4 */
  218. y = j;
  219. /* integer and fractional part modulo one octant */
  220. if( j & 1 ) /* map zeros to origin */
  221. {
  222. j += 1;
  223. y += 1.0;
  224. }
  225. j &= 7;
  226. if( j > 3)
  227. {
  228. j -=4;
  229. sign = -sign;
  230. }
  231. if( j > 1 )
  232. sign = -sign;
  233. if( x > lossth )
  234. {
  235. mtherr( "cosf", PLOSS );
  236. x = x - y * PIO4F;
  237. }
  238. else
  239. /* Extended precision modular arithmetic */
  240. x = ((x - y * DP1) - y * DP2) - y * DP3;
  241. z = x * x;
  242. if( (j==1) || (j==2) )
  243. {
  244. y = (((-1.9515295891E-4 * z
  245. + 8.3321608736E-3) * z
  246. - 1.6666654611E-1) * z * x)
  247. + x;
  248. }
  249. else
  250. {
  251. y = (( 2.443315711809948E-005 * z
  252. - 1.388731625493765E-003) * z
  253. + 4.166664568298827E-002) * z * z;
  254. y -= 0.5 * z;
  255. y += 1.0;
  256. }
  257. if(sign < 0)
  258. y = -y;
  259. return( y );
  260. }