asinh.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* asinh.c
  2. *
  3. * Inverse hyperbolic sine
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double x, y, asinh();
  10. *
  11. * y = asinh( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns inverse hyperbolic sine of argument.
  18. *
  19. * If |x| < 0.5, the function is approximated by a rational
  20. * form x + x**3 P(x)/Q(x). Otherwise,
  21. *
  22. * asinh(x) = log( x + sqrt(1 + x*x) ).
  23. *
  24. *
  25. *
  26. * ACCURACY:
  27. *
  28. * Relative error:
  29. * arithmetic domain # trials peak rms
  30. * DEC -3,3 75000 4.6e-17 1.1e-17
  31. * IEEE -1,1 30000 3.7e-16 7.8e-17
  32. * IEEE 1,3 30000 2.5e-16 6.7e-17
  33. *
  34. */
  35. /* asinh.c */
  36. /*
  37. Cephes Math Library Release 2.8: June, 2000
  38. Copyright 1984, 1995, 2000 by Stephen L. Moshier
  39. */
  40. #include <math.h>
  41. #ifdef UNK
  42. static double P[] = {
  43. -4.33231683752342103572E-3,
  44. -5.91750212056387121207E-1,
  45. -4.37390226194356683570E0,
  46. -9.09030533308377316566E0,
  47. -5.56682227230859640450E0
  48. };
  49. static double Q[] = {
  50. /* 1.00000000000000000000E0,*/
  51. 1.28757002067426453537E1,
  52. 4.86042483805291788324E1,
  53. 6.95722521337257608734E1,
  54. 3.34009336338516356383E1
  55. };
  56. #endif
  57. #ifdef DEC
  58. static unsigned short P[] = {
  59. 0136215,0173033,0110410,0105475,
  60. 0140027,0076361,0020056,0164520,
  61. 0140613,0173401,0160136,0053142,
  62. 0141021,0070744,0000503,0176261,
  63. 0140662,0021550,0073106,0133351
  64. };
  65. static unsigned short Q[] = {
  66. /* 0040200,0000000,0000000,0000000,*/
  67. 0041116,0001336,0034120,0173054,
  68. 0041502,0065300,0013144,0021231,
  69. 0041613,0022376,0035516,0153063,
  70. 0041405,0115216,0054265,0004557
  71. };
  72. #endif
  73. #ifdef IBMPC
  74. static unsigned short P[] = {
  75. 0x1168,0x7221,0xbec3,0xbf71,
  76. 0xdd2a,0x2405,0xef9e,0xbfe2,
  77. 0xcacc,0x3c0b,0x7ee0,0xc011,
  78. 0x7f96,0x8028,0x2e3c,0xc022,
  79. 0xd6dd,0x0ec8,0x446d,0xc016
  80. };
  81. static unsigned short Q[] = {
  82. /* 0x0000,0x0000,0x0000,0x3ff0,*/
  83. 0x1ec5,0xc70a,0xc05b,0x4029,
  84. 0x8453,0x02cc,0x4d58,0x4048,
  85. 0xdac6,0xc769,0x649f,0x4051,
  86. 0xa12e,0xcb16,0xb351,0x4040
  87. };
  88. #endif
  89. #ifdef MIEEE
  90. static unsigned short P[] = {
  91. 0xbf71,0xbec3,0x7221,0x1168,
  92. 0xbfe2,0xef9e,0x2405,0xdd2a,
  93. 0xc011,0x7ee0,0x3c0b,0xcacc,
  94. 0xc022,0x2e3c,0x8028,0x7f96,
  95. 0xc016,0x446d,0x0ec8,0xd6dd
  96. };
  97. static unsigned short Q[] = {
  98. 0x4029,0xc05b,0xc70a,0x1ec5,
  99. 0x4048,0x4d58,0x02cc,0x8453,
  100. 0x4051,0x649f,0xc769,0xdac6,
  101. 0x4040,0xb351,0xcb16,0xa12e
  102. };
  103. #endif
  104. #ifdef ANSIPROT
  105. extern double polevl ( double, void *, int );
  106. extern double p1evl ( double, void *, int );
  107. extern double sqrt ( double );
  108. extern double log ( double );
  109. #else
  110. double log(), sqrt(), polevl(), p1evl();
  111. #endif
  112. extern double LOGE2, INFINITY;
  113. double asinh(xx)
  114. double xx;
  115. {
  116. double a, z, x;
  117. int sign;
  118. #ifdef MINUSZERO
  119. if( xx == 0.0 )
  120. return(xx);
  121. #endif
  122. if( xx < 0.0 )
  123. {
  124. sign = -1;
  125. x = -xx;
  126. }
  127. else
  128. {
  129. sign = 1;
  130. x = xx;
  131. }
  132. if( x > 1.0e8 )
  133. {
  134. #ifdef INFINITIES
  135. if( x == INFINITY )
  136. return(xx);
  137. #endif
  138. return( sign * (log(x) + LOGE2) );
  139. }
  140. z = x * x;
  141. if( x < 0.5 )
  142. {
  143. a = ( polevl(z, P, 4)/p1evl(z, Q, 4) ) * z;
  144. a = a * x + x;
  145. if( sign < 0 )
  146. a = -a;
  147. return(a);
  148. }
  149. a = sqrt( z + 1.0 );
  150. return( sign * log(x + a) );
  151. }