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 * @(#)e_cosh.c 1.3 95/01/18
26 */
27
28 #include "jerry-libm-internal.h"
29
30 /* cosh(x)
31 * Method:
32 * mathematically cosh(x) if defined to be (exp(x) + exp(-x)) / 2
33 * 1. Replace x by |x| (cosh(x) = cosh(-x)).
34 * 2.
35 * [ exp(x) - 1 ]^2
36 * 0 <= x <= ln2/2 : cosh(x) := 1 + -------------------
37 * 2*exp(x)
38 *
39 * exp(x) + 1/exp(x)
40 * ln2/2 <= x <= 22 : cosh(x) := -------------------
41 * 2
42 *
43 * 22 <= x <= lnovft : cosh(x) := exp(x)/2
44 * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2)
45 * ln2ovft < x : cosh(x) := huge * huge (overflow)
46 *
47 * Special cases:
48 * cosh(x) is |x| if x is +INF, -INF, or NaN.
49 * only cosh(0) = 1 is exact for finite x.
50 */
51
52 #define one 1.0
53 #define half 0.5
54 #define huge 1.0e300
55
56 double
cosh(double x)57 cosh (double x)
58 {
59 double t, w;
60 int ix;
61 unsigned lx;
62
63 /* High word of |x|. */
64 ix = __HI (x);
65 ix &= 0x7fffffff;
66
67 /* x is INF or NaN */
68 if (ix >= 0x7ff00000)
69 {
70 return x * x;
71 }
72 /* |x| in [0, 0.5 * ln2], return 1 + expm1(|x|)^2 / (2 * exp(|x|)) */
73 if (ix < 0x3fd62e43)
74 {
75 t = expm1 (fabs (x));
76 w = one + t;
77 if (ix < 0x3c800000)
78 {
79 /* cosh(tiny) = 1 */
80 return w;
81 }
82 return one + (t * t) / (w + w);
83 }
84
85 /* |x| in [0.5 * ln2, 22], return (exp(|x|) + 1 / exp(|x|) / 2; */
86 if (ix < 0x40360000)
87 {
88 t = exp (fabs (x));
89 return half * t + half / t;
90 }
91
92 /* |x| in [22, log(maxdouble)] return half * exp(|x|) */
93 if (ix < 0x40862E42)
94 {
95 return half * exp (fabs (x));
96 }
97 /* |x| in [log(maxdouble), overflowthresold] */
98 lx = ((1 >> 29) + (unsigned int) x);
99 if ((ix < 0x408633CE) ||
100 ((ix == 0x408633ce) && (lx <= (unsigned) 0x8fb9f87d)))
101 {
102 w = exp (half * fabs (x));
103 t = half * w;
104 return t * w;
105 }
106
107 /* |x| > overflowthresold, cosh(x) overflow */
108 return huge * huge;
109 } /* cosh */
110
111 #undef one
112 #undef half
113 #undef huge
114