• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * This file is based on work under the following copyright and permission
16  * notice:
17  *
18  *     Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
19  *
20  *     Developed at SunSoft, a Sun Microsystems, Inc. business.
21  *     Permission to use, copy, modify, and distribute this
22  *     software is freely granted, provided that this notice
23  *     is preserved.
24  *
25  *     @(#)s_tanh.c 1.3 95/01/18
26  */
27 
28 #include "jerry-libm-internal.h"
29 
30 /* tanh(x)
31  * Return the Hyperbolic Tangent of x
32  *
33  * Method:
34  *                                 x   -x
35  *                                e -  e
36  *  0. tanh(x) is defined to be -----------
37  *                                 x    -x
38  *                                e  +  e
39  *
40  *  1. reduce x to non-negative by tanh(-x) = -tanh(x).
41  *  2.  0      <= x <= 2**-55 : tanh(x) := x * (one + x)
42  *
43  *                                          -t
44  *      2**-55 <  x <=  1     : tanh(x) := -----; t = expm1(-2x)
45  *                                         t + 2
46  *
47  *                                               2
48  *      1      <= x <=  22.0  : tanh(x) := 1-  ----- ; t = expm1(2x)
49  *                                             t + 2
50  *
51  *      22.0   <  x <= INF    : tanh(x) := 1.
52  *
53  * Special cases:
54  *  tanh(NaN) is NaN;
55  *  only tanh(0) = 0 is exact for finite x.
56  */
57 #define one 1.0
58 #define two 2.0
59 #define tiny 1.0e-300
60 
61 double
tanh(double x)62 tanh (double x)
63 {
64   double t, z;
65   int jx, ix;
66 
67   /* High word of |x|. */
68   jx = __HI (x);
69   ix = jx & 0x7fffffff;
70 
71   /* x is INF or NaN */
72   if (ix >= 0x7ff00000)
73   {
74     if (jx >= 0)
75     {
76       /* tanh(+-inf) = +-1 */
77       return one / x + one;
78     }
79     else
80     {
81       /* tanh(NaN) = NaN */
82       return one / x - one;
83     }
84   }
85 
86   /* |x| < 22 */
87   if (ix < 0x40360000)
88   {
89     /* |x| < 2**-55 */
90     if (ix < 0x3c800000)
91     {
92       /* tanh(small) = small */
93       return x * (one + x);
94     }
95     if (ix >= 0x3ff00000)
96     {
97       /* |x| >= 1  */
98       t = expm1 (two * fabs (x));
99       z = one - two / (t + two);
100     }
101     else
102     {
103       t = expm1 (-two * fabs (x));
104       z = -t / (t + two);
105     }
106   }
107   else
108   {
109     /* |x| > 22, return +-1 */
110     z = one - tiny; /* raised inexact flag */
111   }
112   return (jx >= 0) ? z : -z;
113 } /* tanh */
114 
115 #undef one
116 #undef two
117 #undef tiny
118