asinhl.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* asinhl.c
  2. *
  3. * Inverse hyperbolic sine, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, asinhl();
  10. *
  11. * y = asinhl( 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. * IEEE -3,3 30000 1.7e-19 3.5e-20
  31. *
  32. */
  33. /*
  34. Cephes Math Library Release 2.7: May, 1998
  35. Copyright 1984, 1991, 1998 by Stephen L. Moshier
  36. */
  37. #include <math.h>
  38. #ifdef UNK
  39. static long double P[] = {
  40. -7.2157234864927687427374E-1L,
  41. -1.3005588097490352458918E1L,
  42. -5.9112383795679709212744E1L,
  43. -9.5372702442289028811361E1L,
  44. -4.9802880260861844539014E1L,
  45. };
  46. static long double Q[] = {
  47. /* 1.0000000000000000000000E0L,*/
  48. 2.8754968540389640419671E1L,
  49. 2.0990255691901160529390E2L,
  50. 5.9265075560893800052658E2L,
  51. 7.0670399135805956780660E2L,
  52. 2.9881728156517107462943E2L,
  53. };
  54. #endif
  55. #ifdef IBMPC
  56. static short P[] = {
  57. 0x8f42,0x2584,0xf727,0xb8b8,0xbffe, XPD
  58. 0x9d56,0x7f7c,0xe38b,0xd016,0xc002, XPD
  59. 0xc518,0xdc2d,0x14bc,0xec73,0xc004, XPD
  60. 0x99fe,0xc18a,0xd2da,0xbebe,0xc005, XPD
  61. 0xb46c,0x3c05,0x263e,0xc736,0xc004, XPD
  62. };
  63. static short Q[] = {
  64. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  65. 0xdfed,0x33db,0x2cf2,0xe60a,0x4003, XPD
  66. 0xf109,0x61ee,0x0df8,0xd1e7,0x4006, XPD
  67. 0xf21e,0xda84,0xa5fa,0x9429,0x4008, XPD
  68. 0x13fc,0xc4e2,0x0e31,0xb0ad,0x4008, XPD
  69. 0x485c,0xad04,0x9cae,0x9568,0x4007, XPD
  70. };
  71. #endif
  72. #ifdef MIEEE
  73. static long P[] = {
  74. 0xbffe0000,0xb8b8f727,0x25848f42,
  75. 0xc0020000,0xd016e38b,0x7f7c9d56,
  76. 0xc0040000,0xec7314bc,0xdc2dc518,
  77. 0xc0050000,0xbebed2da,0xc18a99fe,
  78. 0xc0040000,0xc736263e,0x3c05b46c,
  79. };
  80. static long Q[] = {
  81. /*0x3fff0000,0x80000000,0x00000000,*/
  82. 0x40030000,0xe60a2cf2,0x33dbdfed,
  83. 0x40060000,0xd1e70df8,0x61eef109,
  84. 0x40080000,0x9429a5fa,0xda84f21e,
  85. 0x40080000,0xb0ad0e31,0xc4e213fc,
  86. 0x40070000,0x95689cae,0xad04485c,
  87. };
  88. #endif
  89. extern long double LOGE2L;
  90. #ifdef INFINITIES
  91. extern long double INFINITYL;
  92. #endif
  93. #ifdef ANSIPROT
  94. extern long double logl ( long double );
  95. extern long double sqrtl ( long double );
  96. extern long double polevll ( long double, void *, int );
  97. extern long double p1evll ( long double, void *, int );
  98. extern int isnanl ( long double );
  99. extern int isfinitel ( long double );
  100. #else
  101. long double logl(), sqrtl(), polevll(), p1evll(), isnanl(), isfinitel();
  102. #endif
  103. long double asinhl(x)
  104. long double x;
  105. {
  106. long double a, z;
  107. int sign;
  108. #ifdef NANS
  109. if( isnanl(x) )
  110. return(x);
  111. #endif
  112. #ifdef MINUSZERO
  113. if( x == 0.0L )
  114. return(x);
  115. #endif
  116. #ifdef INFINITIES
  117. if( !isfinitel(x) )
  118. return(x);
  119. #endif
  120. if( x < 0.0L )
  121. {
  122. sign = -1;
  123. x = -x;
  124. }
  125. else
  126. sign = 1;
  127. if( x > 1.0e10L )
  128. {
  129. return( sign * (logl(x) + LOGE2L) );
  130. }
  131. z = x * x;
  132. if( x < 0.5L )
  133. {
  134. a = ( polevll(z, P, 4)/p1evll(z, Q, 5) ) * z;
  135. a = a * x + x;
  136. if( sign < 0 )
  137. a = -a;
  138. return(a);
  139. }
  140. a = sqrtl( z + 1.0L );
  141. return( sign * logl(x + a) );
  142. }