acoshl.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* acoshl.c
  2. *
  3. * Inverse hyperbolic cosine, long double precision
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double x, y, acoshl();
  10. *
  11. * y = acoshl( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns inverse hyperbolic cosine of argument.
  18. *
  19. * If 1 <= x < 1.5, a rational approximation
  20. *
  21. * sqrt(2z) * P(z)/Q(z)
  22. *
  23. * where z = x-1, is used. Otherwise,
  24. *
  25. * acosh(x) = log( x + sqrt( (x-1)(x+1) ).
  26. *
  27. *
  28. *
  29. * ACCURACY:
  30. *
  31. * Relative error:
  32. * arithmetic domain # trials peak rms
  33. * IEEE 1,3 30000 2.0e-19 3.9e-20
  34. *
  35. *
  36. * ERROR MESSAGES:
  37. *
  38. * message condition value returned
  39. * acoshl domain |x| < 1 0.0
  40. *
  41. */
  42. /* acosh.c */
  43. /*
  44. Cephes Math Library Release 2.7: May, 1998
  45. Copyright 1984, 1991, 1998 by Stephen L. Moshier
  46. */
  47. /* acosh(1+x) = sqrt(2x) * R(x), interval 0 < x < 0.5 */
  48. #include <math.h>
  49. #ifdef UNK
  50. static long double P[] = {
  51. 2.9071989653343333587238E-5L,
  52. 3.2906030801088967279449E-3L,
  53. 6.3034445964862182128388E-2L,
  54. 4.1587081802731351459504E-1L,
  55. 1.0989714347599256302467E0L,
  56. 9.9999999999999999999715E-1L,
  57. };
  58. static long double Q[] = {
  59. 1.0443462486787584738322E-4L,
  60. 6.0085845375571145826908E-3L,
  61. 8.7750439986662958343370E-2L,
  62. 4.9564621536841869854584E-1L,
  63. 1.1823047680932589605190E0L,
  64. 1.0000000000000000000028E0L,
  65. };
  66. #endif
  67. #ifdef IBMPC
  68. static unsigned short P[] = {
  69. 0x4536,0x4dba,0x9f55,0xf3df,0x3fef, XPD
  70. 0x23a5,0xf9aa,0x289c,0xd7a7,0x3ff6, XPD
  71. 0x7e8b,0x8645,0x341f,0x8118,0x3ffb, XPD
  72. 0x0fd5,0x937f,0x0515,0xd4ed,0x3ffd, XPD
  73. 0x2364,0xc41b,0x1891,0x8cab,0x3fff, XPD
  74. 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
  75. };
  76. static short Q[] = {
  77. 0x1e7c,0x4f16,0xe98c,0xdb03,0x3ff1, XPD
  78. 0xc319,0xc272,0xa90a,0xc4e3,0x3ff7, XPD
  79. 0x2f83,0x9e5e,0x80af,0xb3b6,0x3ffb, XPD
  80. 0xe1e0,0xc97c,0x573a,0xfdc5,0x3ffd, XPD
  81. 0xcdf2,0x6ec5,0xc33c,0x9755,0x3fff, XPD
  82. 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD
  83. };
  84. #endif
  85. #ifdef MIEEE
  86. static long P[] = {
  87. 0x3fef0000,0xf3df9f55,0x4dba4536,
  88. 0x3ff60000,0xd7a7289c,0xf9aa23a5,
  89. 0x3ffb0000,0x8118341f,0x86457e8b,
  90. 0x3ffd0000,0xd4ed0515,0x937f0fd5,
  91. 0x3fff0000,0x8cab1891,0xc41b2364,
  92. 0x3fff0000,0x80000000,0x00000000,
  93. };
  94. static long Q[] = {
  95. 0x3ff10000,0xdb03e98c,0x4f161e7c,
  96. 0x3ff70000,0xc4e3a90a,0xc272c319,
  97. 0x3ffb0000,0xb3b680af,0x9e5e2f83,
  98. 0x3ffd0000,0xfdc5573a,0xc97ce1e0,
  99. 0x3fff0000,0x9755c33c,0x6ec5cdf2,
  100. 0x3fff0000,0x80000000,0x00000000,
  101. };
  102. #endif
  103. extern long double LOGE2L;
  104. #ifdef INFINITIES
  105. extern long double INFINITYL;
  106. #endif
  107. #ifdef NANS
  108. extern long double NANL;
  109. #endif
  110. #ifdef ANSIPROT
  111. extern long double logl ( long double );
  112. extern long double sqrtl ( long double );
  113. extern long double polevll ( long double, void *, int );
  114. extern int isnanl ( long double );
  115. #else
  116. long double logl(), sqrtl(), polevll(), isnanl();
  117. #endif
  118. long double acoshl(x)
  119. long double x;
  120. {
  121. long double a, z;
  122. #ifdef NANS
  123. if( isnanl(x) )
  124. return(x);
  125. #endif
  126. if( x < 1.0L )
  127. {
  128. mtherr( "acoshl", DOMAIN );
  129. #ifdef NANS
  130. return(NANL);
  131. #else
  132. return(0.0L);
  133. #endif
  134. }
  135. if( x > 1.0e10 )
  136. {
  137. #ifdef INFINITIES
  138. if( x == INFINITYL )
  139. return( INFINITYL );
  140. #endif
  141. return( logl(x) + LOGE2L );
  142. }
  143. z = x - 1.0L;
  144. if( z < 0.5L )
  145. {
  146. a = sqrtl(2.0L*z) * (polevll(z, P, 5) / polevll(z, Q, 5) );
  147. return( a );
  148. }
  149. a = sqrtl( z*(x+1.0L) );
  150. return( logl(x + a) );
  151. }