First public contribution.
3 * Portions Copyright (c) 1993-1999 Nokia Corporation and/or its subsidiary(-ies).
8 /* @(#)s_tanh.c 5.1 93/09/24 */
10 * ====================================================
11 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
13 * Developed at SunPro, a Sun Microsystems, Inc. business.
14 * Permission to use, copy, modify, and distribute this
15 * software is freely granted, provided that this notice
17 * ====================================================
23 <<tanh>>, <<tanhf>>---hyperbolic tangent
32 double tanh(double <[x]>);
33 float tanhf(float <[x]>);
46 <<tanh>> computes the hyperbolic tangent of
47 the argument <[x]>. Angles are specified in radians.
49 <<tanh(<[x]>)>> is defined as
50 . sinh(<[x]>)/cosh(<[x]>)
52 <<tanhf>> is identical, save that it takes and returns <<float>> values.
55 The hyperbolic tangent of <[x]> is returned.
58 <<tanh>> is ANSI C. <<tanhf>> is an extension.
63 * Return the Hyperbolic Tangent of x
68 * 0. tanh(x) is defined to be -----------
71 * 1. reduce x to non-negative by tanh(-x) = -tanh(x).
72 * 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x)
74 * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x)
77 * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x)
79 * 22.0 < x <= INF : tanh(x) := 1.
83 * only tanh(0)=0 is exact for finite argument.
88 static const double one=1.0, two=2.0, tiny = 1.0e-300;
91 Calculate hyperbolic tangent.
92 @return hyperbolic tangent of x.
93 @param x Angle expressed in radians (180 degrees = PI radians).
95 EXPORT_C double tanh(double x) __SOFTFP
100 /* High word of |x|. */
104 /* x is INF or NaN */
106 if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */
107 else return one/x-one; /* tanh(NaN) = NaN */
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);
118 t = expm1(-two*fabs(x));
121 /* |x| > 22, return +-1 */
123 z = one - tiny; /* raised inexact flag */
125 return (jx>=0)? z: -z;