home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / hobby / palmoon / palmoon.EXE / s_tanh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-16  |  2.4 KB  |  96 lines

  1. // 15 August 1997, Rick Huebner:  Small changes made to adapt for MathLib
  2.  
  3. /* @(#)s_tanh.c 5.1 93/09/24 */
  4. /*
  5.  * ====================================================
  6.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  7.  *
  8.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software is freely granted, provided that this notice
  11.  * is preserved.
  12.  * ====================================================
  13.  */
  14.  
  15. #if defined(LIBM_SCCS) && !defined(lint)
  16. static char rcsid[] = "$NetBSD: s_tanh.c,v 1.7 1995/05/10 20:48:22 jtc Exp $";
  17. #endif
  18.  
  19. /* Tanh(x)
  20.  * Return the Hyperbolic Tangent of x
  21.  *
  22.  * Method :
  23.  *                       x    -x
  24.  *                      e  - e
  25.  *    0. tanh(x) is defined to be -----------
  26.  *                       x    -x
  27.  *                      e  + e
  28.  *    1. reduce x to non-negative by tanh(-x) = -tanh(x).
  29.  *    2.  0      <= x <= 2**-55 : tanh(x) := x*(one+x)
  30.  *                            -t
  31.  *        2**-55 <  x <=  1     : tanh(x) := -----; t = expm1(-2x)
  32.  *                           t + 2
  33.  *                             2
  34.  *        1      <= x <=  22.0  : tanh(x) := 1-  ----- ; t=expm1(2x)
  35.  *                           t + 2
  36.  *        22.0   <  x <= INF    : tanh(x) := 1.
  37.  *
  38.  * Special cases:
  39.  *    tanh(NaN) is NaN;
  40.  *    only tanh(0)=0 is exact for finite argument.
  41.  */
  42.  
  43. #include "math.h"
  44. #include "math_private.h"
  45.  
  46. #ifdef __STDC__
  47. static const double one=1.0, two=2.0, tiny = 1.0e-300;
  48. #else
  49. static double one=1.0, two=2.0, tiny = 1.0e-300;
  50. #endif
  51.  
  52. #ifdef __STDC__
  53.     double __tanh(double x)
  54. #else
  55.     double __tanh(x)
  56.     double x;
  57. #endif
  58. {
  59.     double t,z;
  60.     int32_t jx,ix,lx;
  61.  
  62.     /* High word of |x|. */
  63.     EXTRACT_WORDS(jx,lx,x);
  64.     ix = jx&0x7fffffff;
  65.  
  66.     /* x is INF or NaN */
  67.     if(ix>=0x7ff00000) {
  68.         if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
  69.         else       return one/x-one;    /* tanh(NaN) = NaN */
  70.     }
  71.  
  72.     /* |x| < 22 */
  73.     if (ix < 0x40360000) {        /* |x|<22 */
  74.         if ((ix | lx) == 0)
  75.         return x;        /* x == +-0 */
  76.         if (ix<0x3c800000)         /* |x|<2**-55 */
  77.         return x*(one+x);        /* tanh(small) = small */
  78.         if (ix>=0x3ff00000) {    /* |x|>=1  */
  79.         t = __expm1(two*__fabs(x));
  80.         z = one - two/(t+two);
  81.         } else {
  82.             t = __expm1(-two*__fabs(x));
  83.             z= -t/(t+two);
  84.         }
  85.     /* |x| > 22, return +-1 */
  86.     } else {
  87.         z = one - tiny;        /* raised inexact flag */
  88.     }
  89.     return (jx>=0)? z: -z;
  90. }
  91. weak_alias (__tanh, tanh)
  92. #ifdef NO_LONG_DOUBLE
  93. strong_alias (__tanh, __tanhl)
  94. weak_alias (__tanh, tanhl)
  95. #endif
  96.