[444] | 1 | |
---|
| 2 | /* @(#)z_tanh.c 1.0 98/08/13 */ |
---|
| 3 | /***************************************************************** |
---|
| 4 | * The following routines are coded directly from the algorithms |
---|
| 5 | * and coefficients given in "Software Manual for the Elementary |
---|
| 6 | * Functions" by William J. Cody, Jr. and William Waite, Prentice |
---|
| 7 | * Hall, 1980. |
---|
| 8 | *****************************************************************/ |
---|
| 9 | |
---|
| 10 | /* |
---|
| 11 | |
---|
| 12 | FUNCTION |
---|
| 13 | <<tanh>>, <<tanhf>>---hyperbolic tangent |
---|
| 14 | |
---|
| 15 | INDEX |
---|
| 16 | tanh |
---|
| 17 | INDEX |
---|
| 18 | tanhf |
---|
| 19 | |
---|
| 20 | SYNOPSIS |
---|
| 21 | #include <math.h> |
---|
| 22 | double tanh(double <[x]>); |
---|
| 23 | float tanhf(float <[x]>); |
---|
| 24 | |
---|
| 25 | DESCRIPTION |
---|
| 26 | |
---|
| 27 | <<tanh>> computes the hyperbolic tangent of |
---|
| 28 | the argument <[x]>. Angles are specified in radians. |
---|
| 29 | |
---|
| 30 | <<tanh(<[x]>)>> is defined as |
---|
| 31 | . sinh(<[x]>)/cosh(<[x]>) |
---|
| 32 | |
---|
| 33 | <<tanhf>> is identical, save that it takes and returns <<float>> values. |
---|
| 34 | |
---|
| 35 | RETURNS |
---|
| 36 | The hyperbolic tangent of <[x]> is returned. |
---|
| 37 | |
---|
| 38 | PORTABILITY |
---|
| 39 | <<tanh>> is ANSI C. <<tanhf>> is an extension. |
---|
| 40 | |
---|
| 41 | */ |
---|
| 42 | |
---|
| 43 | /****************************************************************** |
---|
| 44 | * Hyperbolic Tangent |
---|
| 45 | * |
---|
| 46 | * Input: |
---|
| 47 | * x - floating point value |
---|
| 48 | * |
---|
| 49 | * Output: |
---|
| 50 | * hyperbolic tangent of x |
---|
| 51 | * |
---|
| 52 | * Description: |
---|
| 53 | * This routine calculates hyperbolic tangent. |
---|
| 54 | * |
---|
| 55 | *****************************************************************/ |
---|
| 56 | |
---|
| 57 | #include <float.h> |
---|
| 58 | #include "fdlibm.h" |
---|
| 59 | #include "zmath.h" |
---|
| 60 | |
---|
| 61 | #ifndef _DOUBLE_IS_32BITS |
---|
| 62 | |
---|
| 63 | static const double LN3_OVER2 = 0.54930614433405484570; |
---|
| 64 | static const double p[] = { -0.16134119023996228053e+4, |
---|
| 65 | -0.99225929672236083313e+2, |
---|
| 66 | -0.96437492777225469787 }; |
---|
| 67 | static const double q[] = { 0.48402357071988688686e+4, |
---|
| 68 | 0.22337720718962312926e+4, |
---|
| 69 | 0.11274474380534949335e+3 }; |
---|
| 70 | |
---|
| 71 | double |
---|
| 72 | tanh (double x) |
---|
| 73 | { |
---|
| 74 | double f, res, g, P, Q, R; |
---|
| 75 | |
---|
| 76 | f = fabs (x); |
---|
| 77 | |
---|
| 78 | /* Check if the input is too big. */ |
---|
| 79 | if (f > BIGX) |
---|
| 80 | res = 1.0; |
---|
| 81 | |
---|
| 82 | else if (f > LN3_OVER2) |
---|
| 83 | res = 1.0 - 2.0 / (exp (2 * f) + 1.0); |
---|
| 84 | |
---|
| 85 | /* Check if the input is too small. */ |
---|
| 86 | else if (f < z_rooteps) |
---|
| 87 | res = f; |
---|
| 88 | |
---|
| 89 | /* Calculate the Taylor series. */ |
---|
| 90 | else |
---|
| 91 | { |
---|
| 92 | g = f * f; |
---|
| 93 | |
---|
| 94 | P = (p[2] * g + p[1]) * g + p[0]; |
---|
| 95 | Q = ((g + q[2]) * g + q[1]) * g + q[0]; |
---|
| 96 | R = g * (P / Q); |
---|
| 97 | |
---|
| 98 | res = f + f * R; |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | if (x < 0.0) |
---|
| 102 | res = -res; |
---|
| 103 | |
---|
| 104 | return (res); |
---|
| 105 | } |
---|
| 106 | |
---|
| 107 | #endif /* _DOUBLE_IS_32BITS */ |
---|