| OLD | NEW |
| 1 // The following is adapted from fdlibm (http://www.netlib.org/fdlibm), | 1 // The following is adapted from fdlibm (http://www.netlib.org/fdlibm), |
| 2 // | 2 // |
| 3 // ==================================================== | 3 // ==================================================== |
| 4 // Copyright (C) 1993-2004 by Sun Microsystems, Inc. All rights reserved. | 4 // Copyright (C) 1993-2004 by Sun Microsystems, Inc. All rights reserved. |
| 5 // | 5 // |
| 6 // Developed at SunSoft, a Sun Microsystems, Inc. business. | 6 // Developed at SunSoft, a Sun Microsystems, Inc. business. |
| 7 // Permission to use, copy, modify, and distribute this | 7 // Permission to use, copy, modify, and distribute this |
| 8 // software is freely granted, provided that this notice | 8 // software is freely granted, provided that this notice |
| 9 // is preserved. | 9 // is preserved. |
| 10 // ==================================================== | 10 // ==================================================== |
| 11 // | 11 // |
| 12 // The original source code covered by the above license above has been | 12 // The original source code covered by the above license above has been |
| 13 // modified significantly by Google Inc. | 13 // modified significantly by Google Inc. |
| 14 // Copyright 2014 the V8 project authors. All rights reserved. | 14 // Copyright 2014 the V8 project authors. All rights reserved. |
| 15 // | 15 // |
| 16 // The following is a straightforward translation of fdlibm routines | 16 // The following is a straightforward translation of fdlibm routines |
| 17 // by Raymond Toy (rtoy@google.com). | 17 // by Raymond Toy (rtoy@google.com). |
| 18 | 18 |
| 19 (function(global, utils) { | 19 (function(global, utils) { |
| 20 | 20 |
| 21 "use strict"; | 21 "use strict"; |
| 22 | 22 |
| 23 %CheckIsBootstrapping(); | 23 %CheckIsBootstrapping(); |
| 24 | 24 |
| 25 // ------------------------------------------------------------------- | 25 // ------------------------------------------------------------------- |
| 26 // Imports | 26 // Imports |
| 27 | 27 |
| 28 var GlobalMath = global.Math; | 28 var GlobalMath = global.Math; |
| 29 var MathAbs; | |
| 30 var MathExpm1; | |
| 31 | 29 |
| 32 utils.Import(function(from) { | 30 utils.Import(function(from) {}); |
| 33 MathAbs = from.MathAbs; | |
| 34 MathExpm1 = from.MathExpm1; | |
| 35 }); | |
| 36 | |
| 37 // ES6 draft 09-27-13, section 20.2.2.30. | |
| 38 // Math.sinh | |
| 39 // Method : | |
| 40 // mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 | |
| 41 // 1. Replace x by |x| (sinh(-x) = -sinh(x)). | |
| 42 // 2. | |
| 43 // E + E/(E+1) | |
| 44 // 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) | |
| 45 // 2 | |
| 46 // | |
| 47 // 22 <= x <= lnovft : sinh(x) := exp(x)/2 | |
| 48 // lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2) | |
| 49 // ln2ovft < x : sinh(x) := x*shuge (overflow) | |
| 50 // | |
| 51 // Special cases: | |
| 52 // sinh(x) is |x| if x is +Infinity, -Infinity, or NaN. | |
| 53 // only sinh(0)=0 is exact for finite x. | |
| 54 // | |
| 55 define KSINH_OVERFLOW = 710.4758600739439; | |
| 56 define TWO_M28 = 3.725290298461914e-9; // 2^-28, empty lower half | |
| 57 define LOG_MAXD = 709.7822265625; // 0x40862e42 00000000, empty lower half | |
| 58 | |
| 59 function MathSinh(x) { | |
| 60 x = x * 1; // Convert to number. | |
| 61 var h = (x < 0) ? -0.5 : 0.5; | |
| 62 // |x| in [0, 22]. return sign(x)*0.5*(E+E/(E+1)) | |
| 63 var ax = MathAbs(x); | |
| 64 if (ax < 22) { | |
| 65 // For |x| < 2^-28, sinh(x) = x | |
| 66 if (ax < TWO_M28) return x; | |
| 67 var t = MathExpm1(ax); | |
| 68 if (ax < 1) return h * (2 * t - t * t / (t + 1)); | |
| 69 return h * (t + t / (t + 1)); | |
| 70 } | |
| 71 // |x| in [22, log(maxdouble)], return 0.5 * exp(|x|) | |
| 72 if (ax < LOG_MAXD) return h * %math_exp(ax); | |
| 73 // |x| in [log(maxdouble), overflowthreshold] | |
| 74 // overflowthreshold = 710.4758600739426 | |
| 75 if (ax <= KSINH_OVERFLOW) { | |
| 76 var w = %math_exp(0.5 * ax); | |
| 77 var t = h * w; | |
| 78 return t * w; | |
| 79 } | |
| 80 // |x| > overflowthreshold or is NaN. | |
| 81 // Return Infinity of the appropriate sign or NaN. | |
| 82 return x * INFINITY; | |
| 83 } | |
| 84 | |
| 85 | |
| 86 // ES6 draft 09-27-13, section 20.2.2.12. | |
| 87 // Math.cosh | |
| 88 // Method : | |
| 89 // mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 | |
| 90 // 1. Replace x by |x| (cosh(x) = cosh(-x)). | |
| 91 // 2. | |
| 92 // [ exp(x) - 1 ]^2 | |
| 93 // 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- | |
| 94 // 2*exp(x) | |
| 95 // | |
| 96 // exp(x) + 1/exp(x) | |
| 97 // ln2/2 <= x <= 22 : cosh(x) := ------------------- | |
| 98 // 2 | |
| 99 // 22 <= x <= lnovft : cosh(x) := exp(x)/2 | |
| 100 // lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) | |
| 101 // ln2ovft < x : cosh(x) := huge*huge (overflow) | |
| 102 // | |
| 103 // Special cases: | |
| 104 // cosh(x) is |x| if x is +INF, -INF, or NaN. | |
| 105 // only cosh(0)=1 is exact for finite x. | |
| 106 // | |
| 107 define KCOSH_OVERFLOW = 710.4758600739439; | |
| 108 | |
| 109 function MathCosh(x) { | |
| 110 x = x * 1; // Convert to number. | |
| 111 var ix = %_DoubleHi(x) & 0x7fffffff; | |
| 112 // |x| in [0,0.5*log2], return 1+expm1(|x|)^2/(2*exp(|x|)) | |
| 113 if (ix < 0x3fd62e43) { | |
| 114 var t = MathExpm1(MathAbs(x)); | |
| 115 var w = 1 + t; | |
| 116 // For |x| < 2^-55, cosh(x) = 1 | |
| 117 if (ix < 0x3c800000) return w; | |
| 118 return 1 + (t * t) / (w + w); | |
| 119 } | |
| 120 // |x| in [0.5*log2, 22], return (exp(|x|)+1/exp(|x|)/2 | |
| 121 if (ix < 0x40360000) { | |
| 122 var t = %math_exp(MathAbs(x)); | |
| 123 return 0.5 * t + 0.5 / t; | |
| 124 } | |
| 125 // |x| in [22, log(maxdouble)], return half*exp(|x|) | |
| 126 if (ix < 0x40862e42) return 0.5 * %math_exp(MathAbs(x)); | |
| 127 // |x| in [log(maxdouble), overflowthreshold] | |
| 128 if (MathAbs(x) <= KCOSH_OVERFLOW) { | |
| 129 var w = %math_exp(0.5 * MathAbs(x)); | |
| 130 var t = 0.5 * w; | |
| 131 return t * w; | |
| 132 } | |
| 133 if (NUMBER_IS_NAN(x)) return x; | |
| 134 // |x| > overflowthreshold. | |
| 135 return INFINITY; | |
| 136 } | |
| 137 | |
| 138 // ES6 draft 09-27-13, section 20.2.2.33. | |
| 139 // Math.tanh(x) | |
| 140 // Method : | |
| 141 // x -x | |
| 142 // e - e | |
| 143 // 0. tanh(x) is defined to be ----------- | |
| 144 // x -x | |
| 145 // e + e | |
| 146 // 1. reduce x to non-negative by tanh(-x) = -tanh(x). | |
| 147 // 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x) | |
| 148 // -t | |
| 149 // 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x) | |
| 150 // t + 2 | |
| 151 // 2 | |
| 152 // 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t = expm1(2x) | |
| 153 // t + 2 | |
| 154 // 22.0 < x <= INF : tanh(x) := 1. | |
| 155 // | |
| 156 // Special cases: | |
| 157 // tanh(NaN) is NaN; | |
| 158 // only tanh(0) = 0 is exact for finite argument. | |
| 159 // | |
| 160 | |
| 161 define TWO_M55 = 2.77555756156289135105e-17; // 2^-55, empty lower half | |
| 162 | |
| 163 function MathTanh(x) { | |
| 164 x = x * 1; // Convert to number. | |
| 165 // x is Infinity or NaN | |
| 166 if (!NUMBER_IS_FINITE(x)) { | |
| 167 if (x > 0) return 1; | |
| 168 if (x < 0) return -1; | |
| 169 return x; | |
| 170 } | |
| 171 | |
| 172 var ax = MathAbs(x); | |
| 173 var z; | |
| 174 // |x| < 22 | |
| 175 if (ax < 22) { | |
| 176 if (ax < TWO_M55) { | |
| 177 // |x| < 2^-55, tanh(small) = small. | |
| 178 return x; | |
| 179 } | |
| 180 if (ax >= 1) { | |
| 181 // |x| >= 1 | |
| 182 var t = MathExpm1(2 * ax); | |
| 183 z = 1 - 2 / (t + 2); | |
| 184 } else { | |
| 185 var t = MathExpm1(-2 * ax); | |
| 186 z = -t / (t + 2); | |
| 187 } | |
| 188 } else { | |
| 189 // |x| > 22, return +/- 1 | |
| 190 z = 1; | |
| 191 } | |
| 192 return (x >= 0) ? z : -z; | |
| 193 } | |
| 194 | 31 |
| 195 //------------------------------------------------------------------- | 32 //------------------------------------------------------------------- |
| 196 | 33 |
| 197 utils.InstallFunctions(GlobalMath, DONT_ENUM, [ | 34 utils.InstallFunctions(GlobalMath, DONT_ENUM, []); |
| 198 "sinh", MathSinh, | |
| 199 "cosh", MathCosh, | |
| 200 "tanh", MathTanh | |
| 201 ]); | |
| 202 | 35 |
| 203 }) | 36 }) |
| OLD | NEW |