sinl.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /* sinl.c
  2. *
  3. * Circular sine, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, sinl();
  10. *
  11. * y = sinl( 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 the Cody
  23. * and Waite polynomial form
  24. * x + x**3 P(x**2) .
  25. * Between pi/4 and pi/2 the cosine is represented as
  26. * 1 - .5 x**2 + x**4 Q(x**2) .
  27. *
  28. *
  29. * ACCURACY:
  30. *
  31. * Relative error:
  32. * arithmetic domain # trials peak rms
  33. * IEEE +-5.5e11 200,000 1.2e-19 2.9e-20
  34. *
  35. * ERROR MESSAGES:
  36. *
  37. * message condition value returned
  38. * sin total loss x > 2**39 0.0
  39. *
  40. * Loss of precision occurs for x > 2**39 = 5.49755813888e11.
  41. * The routine as implemented flags a TLOSS error for
  42. * x > 2**39 and returns 0.0.
  43. */
  44. /* cosl.c
  45. *
  46. * Circular cosine, long double precision
  47. *
  48. *
  49. *
  50. * SYNOPSIS:
  51. *
  52. * long double x, y, cosl();
  53. *
  54. * y = cosl( x );
  55. *
  56. *
  57. *
  58. * DESCRIPTION:
  59. *
  60. * Range reduction is into intervals of pi/4. The reduction
  61. * error is nearly eliminated by contriving an extended precision
  62. * modular arithmetic.
  63. *
  64. * Two polynomial approximating functions are employed.
  65. * Between 0 and pi/4 the cosine is approximated by
  66. * 1 - .5 x**2 + x**4 Q(x**2) .
  67. * Between pi/4 and pi/2 the sine is represented by the Cody
  68. * and Waite polynomial form
  69. * x + x**3 P(x**2) .
  70. *
  71. *
  72. * ACCURACY:
  73. *
  74. * Relative error:
  75. * arithmetic domain # trials peak rms
  76. * IEEE +-5.5e11 50000 1.2e-19 2.9e-20
  77. */
  78. /* sin.c */
  79. /*
  80. Cephes Math Library Release 2.7: May, 1998
  81. Copyright 1985, 1990, 1998 by Stephen L. Moshier
  82. */
  83. #include <math.h>
  84. #ifdef UNK
  85. static long double sincof[7] = {
  86. -7.5785404094842805756289E-13L,
  87. 1.6058363167320443249231E-10L,
  88. -2.5052104881870868784055E-8L,
  89. 2.7557319214064922217861E-6L,
  90. -1.9841269841254799668344E-4L,
  91. 8.3333333333333225058715E-3L,
  92. -1.6666666666666666640255E-1L,
  93. };
  94. static long double coscof[7] = {
  95. 4.7377507964246204691685E-14L,
  96. -1.1470284843425359765671E-11L,
  97. 2.0876754287081521758361E-9L,
  98. -2.7557319214999787979814E-7L,
  99. 2.4801587301570552304991E-5L,
  100. -1.3888888888888872993737E-3L,
  101. 4.1666666666666666609054E-2L,
  102. };
  103. static long double DP1 = 7.853981554508209228515625E-1L;
  104. static long double DP2 = 7.946627356147928367136046290398E-9L;
  105. static long double DP3 = 3.061616997868382943065164830688E-17L;
  106. #endif
  107. #ifdef IBMPC
  108. static short sincof[] = {
  109. 0x4e27,0xe1d6,0x2389,0xd551,0xbfd6, XPD
  110. 0x64d7,0xe706,0x4623,0xb090,0x3fde, XPD
  111. 0x01b1,0xbf34,0x2946,0xd732,0xbfe5, XPD
  112. 0xc8f7,0x9845,0x1d29,0xb8ef,0x3fec, XPD
  113. 0x6514,0x0c53,0x00d0,0xd00d,0xbff2, XPD
  114. 0x569a,0x8888,0x8888,0x8888,0x3ff8, XPD
  115. 0xaa97,0xaaaa,0xaaaa,0xaaaa,0xbffc, XPD
  116. };
  117. static short coscof[] = {
  118. 0x7436,0x6f99,0x8c3a,0xd55e,0x3fd2, XPD
  119. 0x2f37,0x58f4,0x920f,0xc9c9,0xbfda, XPD
  120. 0x5350,0x659e,0xc648,0x8f76,0x3fe2, XPD
  121. 0x4d2b,0xf5c6,0x7dba,0x93f2,0xbfe9, XPD
  122. 0x53ed,0x0c66,0x00d0,0xd00d,0x3fef, XPD
  123. 0x7b67,0x0b60,0x60b6,0xb60b,0xbff5, XPD
  124. 0xaa9a,0xaaaa,0xaaaa,0xaaaa,0x3ffa, XPD
  125. };
  126. static short P1[] = {0x0000,0x0000,0xda80,0xc90f,0x3ffe, XPD};
  127. static short P2[] = {0x0000,0x0000,0xa300,0x8885,0x3fe4, XPD};
  128. static short P3[] = {0x3707,0xa2e0,0x3198,0x8d31,0x3fc8, XPD};
  129. #define DP1 *(long double *)P1
  130. #define DP2 *(long double *)P2
  131. #define DP3 *(long double *)P3
  132. #endif
  133. #ifdef MIEEE
  134. static long sincof[] = {
  135. 0xbfd60000,0xd5512389,0xe1d64e27,
  136. 0x3fde0000,0xb0904623,0xe70664d7,
  137. 0xbfe50000,0xd7322946,0xbf3401b1,
  138. 0x3fec0000,0xb8ef1d29,0x9845c8f7,
  139. 0xbff20000,0xd00d00d0,0x0c536514,
  140. 0x3ff80000,0x88888888,0x8888569a,
  141. 0xbffc0000,0xaaaaaaaa,0xaaaaaa97,
  142. };
  143. static long coscof[] = {
  144. 0x3fd20000,0xd55e8c3a,0x6f997436,
  145. 0xbfda0000,0xc9c9920f,0x58f42f37,
  146. 0x3fe20000,0x8f76c648,0x659e5350,
  147. 0xbfe90000,0x93f27dba,0xf5c64d2b,
  148. 0x3fef0000,0xd00d00d0,0x0c6653ed,
  149. 0xbff50000,0xb60b60b6,0x0b607b67,
  150. 0x3ffa0000,0xaaaaaaaa,0xaaaaaa9a,
  151. };
  152. static long P1[] = {0x3ffe0000,0xc90fda80,0x00000000};
  153. static long P2[] = {0x3fe40000,0x8885a300,0x00000000};
  154. static long P3[] = {0x3fc80000,0x8d313198,0xa2e03707};
  155. #define DP1 *(long double *)P1
  156. #define DP2 *(long double *)P2
  157. #define DP3 *(long double *)P3
  158. #endif
  159. static long double lossth = 5.49755813888e11L; /* 2^39 */
  160. extern long double PIO4L;
  161. #ifdef ANSIPROT
  162. extern long double polevll ( long double, void *, int );
  163. extern long double floorl ( long double );
  164. extern long double ldexpl ( long double, int );
  165. extern int isnanl ( long double );
  166. extern int isfinitel ( long double );
  167. #else
  168. long double polevll(), floorl(), ldexpl(), isnanl(), isfinitel();
  169. #endif
  170. #ifdef INFINITIES
  171. extern long double INFINITYL;
  172. #endif
  173. #ifdef NANS
  174. extern long double NANL;
  175. #endif
  176. long double sinl(x)
  177. long double x;
  178. {
  179. long double y, z, zz;
  180. int j, sign;
  181. #ifdef NANS
  182. if( isnanl(x) )
  183. return(x);
  184. #endif
  185. #ifdef MINUSZERO
  186. if( x == 0.0L )
  187. return(x);
  188. #endif
  189. #ifdef NANS
  190. if( !isfinitel(x) )
  191. {
  192. mtherr( "sinl", DOMAIN );
  193. #ifdef NANS
  194. return(NANL);
  195. #else
  196. return(0.0L);
  197. #endif
  198. }
  199. #endif
  200. /* make argument positive but save the sign */
  201. sign = 1;
  202. if( x < 0 )
  203. {
  204. x = -x;
  205. sign = -1;
  206. }
  207. if( x > lossth )
  208. {
  209. mtherr( "sinl", TLOSS );
  210. return(0.0L);
  211. }
  212. y = floorl( x/PIO4L ); /* integer part of x/PIO4 */
  213. /* strip high bits of integer part to prevent integer overflow */
  214. z = ldexpl( y, -4 );
  215. z = floorl(z); /* integer part of y/8 */
  216. z = y - ldexpl( z, 4 ); /* y - 16 * (y/16) */
  217. j = z; /* convert to integer for tests on the phase angle */
  218. /* map zeros to origin */
  219. if( j & 1 )
  220. {
  221. j += 1;
  222. y += 1.0L;
  223. }
  224. j = j & 07; /* octant modulo 360 degrees */
  225. /* reflect in x axis */
  226. if( j > 3)
  227. {
  228. sign = -sign;
  229. j -= 4;
  230. }
  231. /* Extended precision modular arithmetic */
  232. z = ((x - y * DP1) - y * DP2) - y * DP3;
  233. zz = z * z;
  234. if( (j==1) || (j==2) )
  235. {
  236. y = 1.0L - ldexpl(zz,-1) + zz * zz * polevll( zz, coscof, 6 );
  237. }
  238. else
  239. {
  240. y = z + z * (zz * polevll( zz, sincof, 6 ));
  241. }
  242. if(sign < 0)
  243. y = -y;
  244. return(y);
  245. }
  246. long double cosl(x)
  247. long double x;
  248. {
  249. long double y, z, zz;
  250. long i;
  251. int j, sign;
  252. #ifdef NANS
  253. if( isnanl(x) )
  254. return(x);
  255. #endif
  256. #ifdef INFINITIES
  257. if( !isfinitel(x) )
  258. {
  259. mtherr( "cosl", DOMAIN );
  260. #ifdef NANS
  261. return(NANL);
  262. #else
  263. return(0.0L);
  264. #endif
  265. }
  266. #endif
  267. /* make argument positive */
  268. sign = 1;
  269. if( x < 0 )
  270. x = -x;
  271. if( x > lossth )
  272. {
  273. mtherr( "cosl", TLOSS );
  274. return(0.0L);
  275. }
  276. y = floorl( x/PIO4L );
  277. z = ldexpl( y, -4 );
  278. z = floorl(z); /* integer part of y/8 */
  279. z = y - ldexpl( z, 4 ); /* y - 16 * (y/16) */
  280. /* integer and fractional part modulo one octant */
  281. i = z;
  282. if( i & 1 ) /* map zeros to origin */
  283. {
  284. i += 1;
  285. y += 1.0L;
  286. }
  287. j = i & 07;
  288. if( j > 3)
  289. {
  290. j -=4;
  291. sign = -sign;
  292. }
  293. if( j > 1 )
  294. sign = -sign;
  295. /* Extended precision modular arithmetic */
  296. z = ((x - y * DP1) - y * DP2) - y * DP3;
  297. zz = z * z;
  298. if( (j==1) || (j==2) )
  299. {
  300. y = z + z * (zz * polevll( zz, sincof, 6 ));
  301. }
  302. else
  303. {
  304. y = 1.0L - ldexpl(zz,-1) + zz * zz * polevll( zz, coscof, 6 );
  305. }
  306. if(sign < 0)
  307. y = -y;
  308. return(y);
  309. }