atanl.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /* atanl.c
  2. *
  3. * Inverse circular tangent, long double precision
  4. * (arctangent)
  5. *
  6. *
  7. *
  8. * SYNOPSIS:
  9. *
  10. * long double x, y, atanl();
  11. *
  12. * y = atanl( x );
  13. *
  14. *
  15. *
  16. * DESCRIPTION:
  17. *
  18. * Returns radian angle between -pi/2 and +pi/2 whose tangent
  19. * is x.
  20. *
  21. * Range reduction is from four intervals into the interval
  22. * from zero to tan( pi/8 ). The approximant uses a rational
  23. * function of degree 3/4 of the form x + x**3 P(x)/Q(x).
  24. *
  25. *
  26. *
  27. * ACCURACY:
  28. *
  29. * Relative error:
  30. * arithmetic domain # trials peak rms
  31. * IEEE -10, 10 150000 1.3e-19 3.0e-20
  32. *
  33. */
  34. /* atan2l()
  35. *
  36. * Quadrant correct inverse circular tangent,
  37. * long double precision
  38. *
  39. *
  40. *
  41. * SYNOPSIS:
  42. *
  43. * long double x, y, z, atan2l();
  44. *
  45. * z = atan2l( y, x );
  46. *
  47. *
  48. *
  49. * DESCRIPTION:
  50. *
  51. * Returns radian angle whose tangent is y/x.
  52. * Define compile time symbol ANSIC = 1 for ANSI standard,
  53. * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range
  54. * 0 to 2PI, args (x,y).
  55. *
  56. *
  57. *
  58. * ACCURACY:
  59. *
  60. * Relative error:
  61. * arithmetic domain # trials peak rms
  62. * IEEE -10, 10 60000 1.7e-19 3.2e-20
  63. * See atan.c.
  64. *
  65. */
  66. /* atan.c */
  67. /*
  68. Cephes Math Library Release 2.7: May, 1998
  69. Copyright 1984, 1990, 1998 by Stephen L. Moshier
  70. */
  71. #include <math.h>
  72. #ifdef UNK
  73. static long double P[] = {
  74. -8.6863818178092187535440E-1L,
  75. -1.4683508633175792446076E1L,
  76. -6.3976888655834347413154E1L,
  77. -9.9988763777265819915721E1L,
  78. -5.0894116899623603312185E1L,
  79. };
  80. static long double Q[] = {
  81. /* 1.00000000000000000000E0L,*/
  82. 2.2981886733594175366172E1L,
  83. 1.4399096122250781605352E2L,
  84. 3.6144079386152023162701E2L,
  85. 3.9157570175111990631099E2L,
  86. 1.5268235069887081006606E2L,
  87. };
  88. /* tan( 3*pi/8 ) */
  89. static long double T3P8 = 2.41421356237309504880169L;
  90. /* tan( pi/8 ) */
  91. static long double TP8 = 4.1421356237309504880169e-1L;
  92. #endif
  93. #ifdef IBMPC
  94. static unsigned short P[] = {
  95. 0x8ece,0xce53,0x1266,0xde5f,0xbffe, XPD
  96. 0x07e6,0xa061,0xa6bf,0xeaef,0xc002, XPD
  97. 0x53ee,0xf291,0x557f,0xffe8,0xc004, XPD
  98. 0xf9d6,0xeda6,0x3f3e,0xc7fa,0xc005, XPD
  99. 0xb6c3,0x6abc,0x9361,0xcb93,0xc004, XPD
  100. };
  101. static unsigned short Q[] = {
  102. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  103. 0x54d4,0x894e,0xe76e,0xb7da,0x4003, XPD
  104. 0x76b9,0x7a46,0xafa2,0x8ffd,0x4006, XPD
  105. 0xe3a9,0xe9c0,0x6bee,0xb4b8,0x4007, XPD
  106. 0xabc1,0x50a7,0xb098,0xc3c9,0x4007, XPD
  107. 0x891c,0x100d,0xae89,0x98ae,0x4006, XPD
  108. };
  109. /* tan( 3*pi/8 ) = 2.41421356237309504880 */
  110. static unsigned short T3P8A[] = {0x3242,0xfcef,0x7999,0x9a82,0x4000, XPD};
  111. #define T3P8 *(long double *)T3P8A
  112. /* tan( pi/8 ) = 0.41421356237309504880 */
  113. static unsigned short TP8A[] = {0x9211,0xe779,0xcccf,0xd413,0x3ffd, XPD};
  114. #define TP8 *(long double *)TP8A
  115. #endif
  116. #ifdef MIEEE
  117. static unsigned long P[] = {
  118. 0xbffe0000,0xde5f1266,0xce538ece,
  119. 0xc0020000,0xeaefa6bf,0xa06107e6,
  120. 0xc0040000,0xffe8557f,0xf29153ee,
  121. 0xc0050000,0xc7fa3f3e,0xeda6f9d6,
  122. 0xc0040000,0xcb939361,0x6abcb6c3,
  123. };
  124. static unsigned long Q[] = {
  125. /*0x3fff0000,0x80000000,0x00000000,*/
  126. 0x40030000,0xb7dae76e,0x894e54d4,
  127. 0x40060000,0x8ffdafa2,0x7a4676b9,
  128. 0x40070000,0xb4b86bee,0xe9c0e3a9,
  129. 0x40070000,0xc3c9b098,0x50a7abc1,
  130. 0x40060000,0x98aeae89,0x100d891c,
  131. };
  132. /* tan( 3*pi/8 ) = 2.41421356237309504880 */
  133. static long T3P8A[] = {0x40000000,0x9a827999,0xfcef3242};
  134. #define T3P8 *(long double *)T3P8A
  135. /* tan( pi/8 ) = 0.41421356237309504880 */
  136. static long TP8A[] = {0x3ffd0000,0xd413cccf,0xe7799211};
  137. #define TP8 *(long double *)TP8A
  138. #endif
  139. #ifdef ANSIPROT
  140. extern long double polevll ( long double, void *, int );
  141. extern long double p1evll ( long double, void *, int );
  142. extern long double fabsl ( long double );
  143. extern int signbitl ( long double );
  144. extern int isnanl ( long double );
  145. long double atanl ( long double );
  146. #else
  147. long double polevll(), p1evll(), fabsl(), signbitl(), isnanl();
  148. long double atanl();
  149. #endif
  150. #ifdef INFINITIES
  151. extern long double INFINITYL;
  152. #endif
  153. #ifdef NANS
  154. extern long double NANL;
  155. #endif
  156. #ifdef MINUSZERO
  157. extern long double NEGZEROL;
  158. #endif
  159. long double atanl(x)
  160. long double x;
  161. {
  162. extern long double PIO2L, PIO4L;
  163. long double y, z;
  164. short sign;
  165. #ifdef MINUSZERO
  166. if( x == 0.0L )
  167. return(x);
  168. #endif
  169. #ifdef INFINITIES
  170. if( x == INFINITYL )
  171. return( PIO2L );
  172. if( x == -INFINITYL )
  173. return( -PIO2L );
  174. #endif
  175. /* make argument positive and save the sign */
  176. sign = 1;
  177. if( x < 0.0L )
  178. {
  179. sign = -1;
  180. x = -x;
  181. }
  182. /* range reduction */
  183. if( x > T3P8 )
  184. {
  185. y = PIO2L;
  186. x = -( 1.0L/x );
  187. }
  188. else if( x > TP8 )
  189. {
  190. y = PIO4L;
  191. x = (x-1.0L)/(x+1.0L);
  192. }
  193. else
  194. y = 0.0L;
  195. /* rational form in x**2 */
  196. z = x * x;
  197. y = y + ( polevll( z, P, 4 ) / p1evll( z, Q, 5 ) ) * z * x + x;
  198. if( sign < 0 )
  199. y = -y;
  200. return(y);
  201. }
  202. /* atan2 */
  203. extern long double PIL, PIO2L, MAXNUML;
  204. #if ANSIC
  205. long double atan2l( y, x )
  206. #else
  207. long double atan2l( x, y )
  208. #endif
  209. long double x, y;
  210. {
  211. long double z, w;
  212. short code;
  213. code = 0;
  214. if( x < 0.0L )
  215. code = 2;
  216. if( y < 0.0L )
  217. code |= 1;
  218. #ifdef NANS
  219. if( isnanl(x) )
  220. return(x);
  221. if( isnanl(y) )
  222. return(y);
  223. #endif
  224. #ifdef MINUSZERO
  225. if( y == 0.0L )
  226. {
  227. if( signbitl(y) )
  228. {
  229. if( x > 0.0L )
  230. z = y;
  231. else if( x < 0.0L )
  232. z = -PIL;
  233. else
  234. {
  235. if( signbitl(x) )
  236. z = -PIL;
  237. else
  238. z = y;
  239. }
  240. }
  241. else /* y is +0 */
  242. {
  243. if( x == 0.0L )
  244. {
  245. if( signbitl(x) )
  246. z = PIL;
  247. else
  248. z = 0.0L;
  249. }
  250. else if( x > 0.0L )
  251. z = 0.0L;
  252. else
  253. z = PIL;
  254. }
  255. return z;
  256. }
  257. if( x == 0.0L )
  258. {
  259. if( y > 0.0L )
  260. z = PIO2L;
  261. else
  262. z = -PIO2L;
  263. return z;
  264. }
  265. #endif /* MINUSZERO */
  266. #ifdef INFINITIES
  267. if( x == INFINITYL )
  268. {
  269. if( y == INFINITYL )
  270. z = 0.25L * PIL;
  271. else if( y == -INFINITYL )
  272. z = -0.25L * PIL;
  273. else if( y < 0.0L )
  274. z = NEGZEROL;
  275. else
  276. z = 0.0L;
  277. return z;
  278. }
  279. if( x == -INFINITYL )
  280. {
  281. if( y == INFINITYL )
  282. z = 0.75L * PIL;
  283. else if( y == -INFINITYL )
  284. z = -0.75L * PIL;
  285. else if( y >= 0.0L )
  286. z = PIL;
  287. else
  288. z = -PIL;
  289. return z;
  290. }
  291. if( y == INFINITYL )
  292. return( PIO2L );
  293. if( y == -INFINITYL )
  294. return( -PIO2L );
  295. #endif /* INFINITIES */
  296. #ifdef INFINITIES
  297. if( x == 0.0L )
  298. #else
  299. if( fabsl(x) <= (fabsl(y) / MAXNUML) )
  300. #endif
  301. {
  302. if( code & 1 )
  303. {
  304. #if ANSIC
  305. return( -PIO2L );
  306. #else
  307. return( 3.0L*PIO2L );
  308. #endif
  309. }
  310. if( y == 0.0L )
  311. return( 0.0L );
  312. return( PIO2L );
  313. }
  314. if( y == 0.0L )
  315. {
  316. if( code & 2 )
  317. return( PIL );
  318. return( 0.0L );
  319. }
  320. switch( code )
  321. {
  322. default:
  323. #if ANSIC
  324. case 0:
  325. case 1: w = 0.0L; break;
  326. case 2: w = PIL; break;
  327. case 3: w = -PIL; break;
  328. #else
  329. case 0: w = 0.0L; break;
  330. case 1: w = 2.0L * PIL; break;
  331. case 2:
  332. case 3: w = PIL; break;
  333. #endif
  334. }
  335. z = w + atanl( y/x );
  336. #ifdef MINUSZERO
  337. if( z == 0.0L && y < 0.0L )
  338. z = NEGZEROL;
  339. #endif
  340. return( z );
  341. }