Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*                                                      tanhl.c
  2.  *
  3.  *      Hyperbolic tangent, long double precision
  4.  *
  5.  *
  6.  *
  7.  * SYNOPSIS:
  8.  *
  9.  * long double x, y, tanhl();
  10.  *
  11.  * y = tanhl( x );
  12.  *
  13.  *
  14.  *
  15.  * DESCRIPTION:
  16.  *
  17.  * Returns hyperbolic tangent of argument in the range MINLOGL to
  18.  * MAXLOGL.
  19.  *
  20.  * A rational function is used for |x| < 0.625.  The form
  21.  * x + x**3 P(x)/Q(x) of Cody _& Waite is employed.
  22.  * Otherwise,
  23.  *    tanh(x) = sinh(x)/cosh(x) = 1  -  2/(exp(2x) + 1).
  24.  *
  25.  *
  26.  *
  27.  * ACCURACY:
  28.  *
  29.  *                      Relative error:
  30.  * arithmetic   domain     # trials      peak         rms
  31.  *    IEEE      -2,2        30000       1.3e-19     2.4e-20
  32.  *
  33.  */
  34. /*
  35. Cephes Math Library Release 2.7:  May, 1998
  36. Copyright 1984, 1987, 1989, 1998 by Stephen L. Moshier
  37. */
  38.  
  39. /*
  40. Modified for mingw
  41. 2002-07-22 Danny Smith <dannysmith@users.sourceforge.net>
  42. */
  43.  
  44. #ifdef __MINGW32__
  45. #include "cephes_mconf.h"
  46. #else
  47. #include "mconf.h"
  48. #endif
  49.  
  50. #ifndef _SET_ERRNO
  51. #define _SET_ERRNO(x)
  52. #endif
  53.  
  54. #ifdef UNK
  55. static long double P[] = {
  56. -6.8473739392677100872869E-5L,
  57. -9.5658283111794641589011E-1L,
  58. -8.4053568599672284488465E1L,
  59. -1.3080425704712825945553E3L,
  60. };
  61. static long double Q[] = {
  62. /* 1.0000000000000000000000E0L,*/
  63.  9.6259501838840336946872E1L,
  64.  1.8218117903645559060232E3L,
  65.  3.9241277114138477845780E3L,
  66. };
  67. #endif
  68.  
  69. #ifdef IBMPC
  70. static unsigned short P[] = {
  71. 0xd2a4,0x1b0c,0x8f15,0x8f99,0xbff1, XPD
  72. 0x5959,0x9111,0x9cc7,0xf4e2,0xbffe, XPD
  73. 0xb576,0xef5e,0x6d57,0xa81b,0xc005, XPD
  74. 0xe3be,0xbfbd,0x5cbc,0xa381,0xc009, XPD
  75. };
  76. static unsigned short Q[] = {
  77. /*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
  78. 0x687f,0xce24,0xdd6c,0xc084,0x4005, XPD
  79. 0x3793,0xc95f,0xfa2f,0xe3b9,0x4009, XPD
  80. 0xd5a2,0x1f9c,0x0b1b,0xf542,0x400a, XPD
  81. };
  82. #endif
  83.  
  84. #ifdef MIEEE
  85. static long P[] = {
  86. 0xbff10000,0x8f998f15,0x1b0cd2a4,
  87. 0xbffe0000,0xf4e29cc7,0x91115959,
  88. 0xc0050000,0xa81b6d57,0xef5eb576,
  89. 0xc0090000,0xa3815cbc,0xbfbde3be,
  90. };
  91. static long Q[] = {
  92. /*0x3fff0000,0x80000000,0x00000000,*/
  93. 0x40050000,0xc084dd6c,0xce24687f,
  94. 0x40090000,0xe3b9fa2f,0xc95f3793,
  95. 0x400a0000,0xf5420b1b,0x1f9cd5a2,
  96. };
  97. #endif
  98.  
  99. #ifndef __MINGW32__
  100. extern long double MAXLOGL;
  101. #ifdef ANSIPROT
  102. extern long double fabsl ( long double );
  103. extern long double expl ( long double );
  104. extern long double polevll ( long double, void *, int );
  105. extern long double p1evll ( long double, void *, int );
  106. #else
  107. long double fabsl(), expl(), polevll(), p1evll();
  108. #endif
  109. #endif /* __MINGW32__ */
  110.  
  111. long double tanhl(x)
  112. long double x;
  113. {
  114. long double s, z;
  115.  
  116. #ifdef MINUSZERO
  117. if( x == 0.0L )
  118.         return(x);
  119. #endif
  120. if (isnanl(x))
  121.         {
  122.         _SET_ERRNO (EDOM);
  123.         return x;
  124.         }
  125.  
  126. z = fabsl(x);
  127. if( z > 0.5L * MAXLOGL )
  128.         {
  129.         _SET_ERRNO (ERANGE);
  130.         if( x > 0 )
  131.                 return( 1.0L );
  132.         else
  133.                 return( -1.0L );
  134.         }
  135. if( z >= 0.625L )
  136.         {
  137.         s = expl(2.0*z);
  138.         z =  1.0L  - 2.0/(s + 1.0L);
  139.         if( x < 0 )
  140.                 z = -z;
  141.         }
  142. else
  143.         {
  144.         s = x * x;
  145.         z = polevll( s, P, 3 )/p1evll(s, Q, 3);
  146.         z = x * s * z;
  147.         z = x + z;
  148.         }
  149. return( z );
  150. }
  151.