home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / gmt_os2.zip / src / math / s_tanh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-16  |  1.9 KB  |  83 lines

  1.  
  2. /* @(#)s_tanh.c 1.3 95/01/18 */
  3. /*
  4.  * ====================================================
  5.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  6.  *
  7.  * Developed at SunSoft, 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. /* Tanh(x)
  15.  * Return the Hyperbolic Tangent of x
  16.  *
  17.  * Method :
  18.  *                       x    -x
  19.  *                      e  - e
  20.  *    0. tanh(x) is defined to be -----------
  21.  *                       x    -x
  22.  *                      e  + e
  23.  *    1. reduce x to non-negative by tanh(-x) = -tanh(x).
  24.  *    2.  0      <= x <= 2**-55 : tanh(x) := x*(one+x)
  25.  *                            -t
  26.  *        2**-55 <  x <=  1     : tanh(x) := -----; t = expm1(-2x)
  27.  *                           t + 2
  28.  *                             2
  29.  *        1      <= x <=  22.0  : tanh(x) := 1-  ----- ; t=expm1(2x)
  30.  *                           t + 2
  31.  *        22.0   <  x <= INF    : tanh(x) := 1.
  32.  *
  33.  * Special cases:
  34.  *    tanh(NaN) is NaN;
  35.  *    only tanh(0)=0 is exact for finite argument.
  36.  */
  37.  
  38. #include "fdlibm.h"
  39.  
  40. #ifdef __STDC__
  41. static const double one=1.0, two=2.0, tiny = 1.0e-300;
  42. #else
  43. static double one=1.0, two=2.0, tiny = 1.0e-300;
  44. #endif
  45.  
  46. #ifdef __STDC__
  47.     double tanh(double x)
  48. #else
  49.     double tanh(x)
  50.     double x;
  51. #endif
  52. {
  53.     double t,z;
  54.     int jx,ix;
  55.  
  56.     /* High word of |x|. */
  57.     jx = __HI(x);
  58.     ix = jx&0x7fffffff;
  59.  
  60.     /* x is INF or NaN */
  61.     if(ix>=0x7ff00000) { 
  62.         if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
  63.         else       return one/x-one;    /* tanh(NaN) = NaN */
  64.     }
  65.  
  66.     /* |x| < 22 */
  67.     if (ix < 0x40360000) {        /* |x|<22 */
  68.         if (ix<0x3c800000)         /* |x|<2**-55 */
  69.         return x*(one+x);        /* tanh(small) = small */
  70.         if (ix>=0x3ff00000) {    /* |x|>=1  */
  71.         t = expm1(two*fabs(x));
  72.         z = one - two/(t+two);
  73.         } else {
  74.             t = expm1(-two*fabs(x));
  75.             z= -t/(t+two);
  76.         }
  77.     /* |x| > 22, return +-1 */
  78.     } else {
  79.         z = one - tiny;        /* raised inexact flag */
  80.     }
  81.     return (jx>=0)? z: -z;
  82. }
  83.