tanl.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /* tanl.c
  2. *
  3. * Circular tangent, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, tanl();
  10. *
  11. * y = tanl( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns the circular tangent of the radian argument x.
  18. *
  19. * Range reduction is modulo pi/4. A rational function
  20. * x + x**3 P(x**2)/Q(x**2)
  21. * is employed in the basic interval [0, pi/4].
  22. *
  23. *
  24. *
  25. * ACCURACY:
  26. *
  27. * Relative error:
  28. * arithmetic domain # trials peak rms
  29. * IEEE +-1.07e9 30000 1.9e-19 4.8e-20
  30. *
  31. * ERROR MESSAGES:
  32. *
  33. * message condition value returned
  34. * tan total loss x > 2^39 0.0
  35. *
  36. */
  37. /* cotl.c
  38. *
  39. * Circular cotangent, long double precision
  40. *
  41. *
  42. *
  43. * SYNOPSIS:
  44. *
  45. * long double x, y, cotl();
  46. *
  47. * y = cotl( x );
  48. *
  49. *
  50. *
  51. * DESCRIPTION:
  52. *
  53. * Returns the circular cotangent of the radian argument x.
  54. *
  55. * Range reduction is modulo pi/4. A rational function
  56. * x + x**3 P(x**2)/Q(x**2)
  57. * is employed in the basic interval [0, pi/4].
  58. *
  59. *
  60. *
  61. * ACCURACY:
  62. *
  63. * Relative error:
  64. * arithmetic domain # trials peak rms
  65. * IEEE +-1.07e9 30000 1.9e-19 5.1e-20
  66. *
  67. *
  68. * ERROR MESSAGES:
  69. *
  70. * message condition value returned
  71. * cot total loss x > 2^39 0.0
  72. * cot singularity x = 0 INFINITYL
  73. *
  74. */
  75. /*
  76. Cephes Math Library Release 2.7: May, 1998
  77. Copyright 1984, 1990, 1998 by Stephen L. Moshier
  78. */
  79. #include <math.h>
  80. #ifdef UNK
  81. static long double P[] = {
  82. -1.3093693918138377764608E4L,
  83. 1.1535166483858741613983E6L,
  84. -1.7956525197648487798769E7L,
  85. };
  86. static long double Q[] = {
  87. /* 1.0000000000000000000000E0L,*/
  88. 1.3681296347069295467845E4L,
  89. -1.3208923444021096744731E6L,
  90. 2.5008380182335791583922E7L,
  91. -5.3869575592945462988123E7L,
  92. };
  93. static long double DP1 = 7.853981554508209228515625E-1L;
  94. static long double DP2 = 7.946627356147928367136046290398E-9L;
  95. static long double DP3 = 3.061616997868382943065164830688E-17L;
  96. #endif
  97. #ifdef IBMPC
  98. static short P[] = {
  99. 0xbc1c,0x79f9,0xc692,0xcc96,0xc00c, XPD
  100. 0xe5b1,0xe4ee,0x652f,0x8ccf,0x4013, XPD
  101. 0xaf9a,0x4c8b,0x5699,0x88ff,0xc017, XPD
  102. };
  103. static short Q[] = {
  104. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  105. 0x8ed4,0x9b2b,0x2f75,0xd5c5,0x400c, XPD
  106. 0xadcd,0x55e4,0xe2c1,0xa13d,0xc013, XPD
  107. 0x7adf,0x56c7,0x7e17,0xbecc,0x4017, XPD
  108. 0x86f6,0xf2d1,0x01e5,0xcd7f,0xc018, XPD
  109. };
  110. static short P1[] = {0x0000,0x0000,0xda80,0xc90f,0x3ffe, XPD};
  111. static short P2[] = {0x0000,0x0000,0xa300,0x8885,0x3fe4, XPD};
  112. static short P3[] = {0x3707,0xa2e0,0x3198,0x8d31,0x3fc8, XPD};
  113. #define DP1 *(long double *)P1
  114. #define DP2 *(long double *)P2
  115. #define DP3 *(long double *)P3
  116. #endif
  117. #ifdef MIEEE
  118. static long P[] = {
  119. 0xc00c0000,0xcc96c692,0x79f9bc1c,
  120. 0x40130000,0x8ccf652f,0xe4eee5b1,
  121. 0xc0170000,0x88ff5699,0x4c8baf9a,
  122. };
  123. static long Q[] = {
  124. /*0x3fff0000,0x80000000,0x00000000,*/
  125. 0x400c0000,0xd5c52f75,0x9b2b8ed4,
  126. 0xc0130000,0xa13de2c1,0x55e4adcd,
  127. 0x40170000,0xbecc7e17,0x56c77adf,
  128. 0xc0180000,0xcd7f01e5,0xf2d186f6,
  129. };
  130. static long P1[] = {0x3ffe0000,0xc90fda80,0x00000000};
  131. static long P2[] = {0x3fe40000,0x8885a300,0x00000000};
  132. static long P3[] = {0x3fc80000,0x8d313198,0xa2e03707};
  133. #define DP1 *(long double *)P1
  134. #define DP2 *(long double *)P2
  135. #define DP3 *(long double *)P3
  136. #endif
  137. static long double lossth = 5.49755813888e11L; /* 2^39 */
  138. extern long double PIO4L;
  139. extern long double MAXNUML;
  140. #ifdef ANSIPROT
  141. extern long double polevll ( long double, void *, int );
  142. extern long double p1evll ( long double, void *, int );
  143. extern long double floorl ( long double );
  144. extern long double ldexpl ( long double, int );
  145. extern int isnanl ( long double );
  146. extern int isfinitel ( long double );
  147. static long double tancotl( long double, int );
  148. #else
  149. long double polevll(), p1evll(), floorl(), ldexpl(), isnanl(), isfinitel();
  150. static long double tancotl();
  151. #endif
  152. #ifdef INFINITIES
  153. extern long double INFINITYL;
  154. #endif
  155. #ifdef NANS
  156. extern long double NANL;
  157. #endif
  158. long double tanl(x)
  159. long double x;
  160. {
  161. #ifdef NANS
  162. if( isnanl(x) )
  163. return(x);
  164. #endif
  165. #ifdef MINUSZERO
  166. if( x == 0.0L )
  167. return(x);
  168. #endif
  169. #ifdef NANS
  170. if( !isfinitel(x) )
  171. {
  172. mtherr( "tanl", DOMAIN );
  173. return(NANL);
  174. }
  175. #endif
  176. return( tancotl(x,0) );
  177. }
  178. long double cotl(x)
  179. long double x;
  180. {
  181. if( x == 0.0L )
  182. {
  183. mtherr( "cotl", SING );
  184. #ifdef INFINITIES
  185. return( INFINITYL );
  186. #else
  187. return( MAXNUML );
  188. #endif
  189. }
  190. return( tancotl(x,1) );
  191. }
  192. static long double tancotl( xx, cotflg )
  193. long double xx;
  194. int cotflg;
  195. {
  196. long double x, y, z, zz;
  197. int j, sign;
  198. /* make argument positive but save the sign */
  199. if( xx < 0.0L )
  200. {
  201. x = -xx;
  202. sign = -1;
  203. }
  204. else
  205. {
  206. x = xx;
  207. sign = 1;
  208. }
  209. if( x > lossth )
  210. {
  211. if( cotflg )
  212. mtherr( "cotl", TLOSS );
  213. else
  214. mtherr( "tanl", TLOSS );
  215. return(0.0L);
  216. }
  217. /* compute x mod PIO4 */
  218. y = floorl( x/PIO4L );
  219. /* strip high bits of integer part */
  220. z = ldexpl( y, -4 );
  221. z = floorl(z); /* integer part of y/16 */
  222. z = y - ldexpl( z, 4 ); /* y - 16 * (y/16) */
  223. /* integer and fractional part modulo one octant */
  224. j = z;
  225. /* map zeros and singularities to origin */
  226. if( j & 1 )
  227. {
  228. j += 1;
  229. y += 1.0L;
  230. }
  231. z = ((x - y * DP1) - y * DP2) - y * DP3;
  232. zz = z * z;
  233. if( zz > 1.0e-20L )
  234. y = z + z * (zz * polevll( zz, P, 2 )/p1evll(zz, Q, 4));
  235. else
  236. y = z;
  237. if( j & 2 )
  238. {
  239. if( cotflg )
  240. y = -y;
  241. else
  242. y = -1.0L/y;
  243. }
  244. else
  245. {
  246. if( cotflg )
  247. y = 1.0L/y;
  248. }
  249. if( sign < 0 )
  250. y = -y;
  251. return( y );
  252. }