Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. /* @(#)s_tanh.c 5.1 93/09/24 */
  3. /*
  4.  * ====================================================
  5.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  6.  *
  7.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software is freely granted, provided that this notice
  10.  * is preserved.
  11.  * ====================================================
  12.  */
  13.  
  14. /*
  15.  
  16. FUNCTION
  17.         <<tanh>>, <<tanhf>>---hyperbolic tangent
  18.  
  19. INDEX
  20. tanh
  21. INDEX
  22. tanhf
  23.  
  24. ANSI_SYNOPSIS
  25.         #include <math.h>
  26.         double tanh(double <[x]>);
  27.         float tanhf(float <[x]>);
  28.  
  29. TRAD_SYNOPSIS
  30.         #include <math.h>
  31.         double tanh(<[x]>)
  32.         double <[x]>;
  33.  
  34.         float tanhf(<[x]>)
  35.         float <[x]>;
  36.  
  37.  
  38. DESCRIPTION
  39.  
  40. <<tanh>> computes the hyperbolic tangent of
  41. the argument <[x]>.  Angles are specified in radians.  
  42.  
  43. <<tanh(<[x]>)>> is defined as
  44. . sinh(<[x]>)/cosh(<[x]>)
  45.        
  46. <<tanhf>> is identical, save that it takes and returns <<float>> values.
  47.  
  48. RETURNS
  49. The hyperbolic tangent of <[x]> is returned.
  50.  
  51. PORTABILITY
  52. <<tanh>> is ANSI C.  <<tanhf>> is an extension.
  53.  
  54. */
  55.  
  56. /* Tanh(x)
  57.  * Return the Hyperbolic Tangent of x
  58.  *
  59.  * Method :
  60.  *                                     x    -x
  61.  *                                    e  - e
  62.  *      0. tanh(x) is defined to be -----------
  63.  *                                     x    -x
  64.  *                                    e  + e
  65.  *      1. reduce x to non-negative by tanh(-x) = -tanh(x).
  66.  *      2.  0      <= x <= 2**-55 : tanh(x) := x*(one+x)
  67.  *                                              -t
  68.  *          2**-55 <  x <=  1     : tanh(x) := -----; t = expm1(-2x)
  69.  *                                             t + 2
  70.  *                                                   2
  71.  *          1      <= x <=  22.0  : tanh(x) := 1-  ----- ; t=expm1(2x)
  72.  *                                                 t + 2
  73.  *          22.0   <  x <= INF    : tanh(x) := 1.
  74.  *
  75.  * Special cases:
  76.  *      tanh(NaN) is NaN;
  77.  *      only tanh(0)=0 is exact for finite argument.
  78.  */
  79.  
  80. #include "fdlibm.h"
  81.  
  82. #ifndef _DOUBLE_IS_32BITS
  83.  
  84. #ifdef __STDC__
  85. static const double one=1.0, two=2.0, tiny = 1.0e-300;
  86. #else
  87. static double one=1.0, two=2.0, tiny = 1.0e-300;
  88. #endif
  89.  
  90. #ifdef __STDC__
  91.         double tanh(double x)
  92. #else
  93.         double tanh(x)
  94.         double x;
  95. #endif
  96. {
  97.         double t,z;
  98.         __int32_t jx,ix;
  99.  
  100.     /* High word of |x|. */
  101.         GET_HIGH_WORD(jx,x);
  102.         ix = jx&0x7fffffff;
  103.  
  104.     /* x is INF or NaN */
  105.         if(ix>=0x7ff00000) {
  106.             if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
  107.             else       return one/x-one;    /* tanh(NaN) = NaN */
  108.         }
  109.  
  110.     /* |x| < 22 */
  111.         if (ix < 0x40360000) {          /* |x|<22 */
  112.             if (ix<0x3c800000)          /* |x|<2**-55 */
  113.                 return x*(one+x);       /* tanh(small) = small */
  114.             if (ix>=0x3ff00000) {       /* |x|>=1  */
  115.                 t = expm1(two*fabs(x));
  116.                 z = one - two/(t+two);
  117.             } else {
  118.                 t = expm1(-two*fabs(x));
  119.                 z= -t/(t+two);
  120.             }
  121.     /* |x| > 22, return +-1 */
  122.         } else {
  123.             z = one - tiny;             /* raised inexact flag */
  124.         }
  125.         return (jx>=0)? z: -z;
  126. }
  127.  
  128. #endif /* _DOUBLE_IS_32BITS */
  129.