| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 var rngstate; // Initialized to a Uint32Array during genesis. | 5 var rngstate; // Initialized to a Uint32Array during genesis. |
| 6 | 6 |
| 7 var $abs; | 7 var $abs; |
| 8 var $exp; | 8 var $exp; |
| 9 var $floor; | 9 var $floor; |
| 10 var $max; | 10 var $max; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 if (arg1 == arg2) { | 81 if (arg1 == arg2) { |
| 82 // Make sure -0 is considered less than +0. | 82 // Make sure -0 is considered less than +0. |
| 83 return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg2 : arg1; | 83 return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg2 : arg1; |
| 84 } | 84 } |
| 85 // All comparisons failed, one of the arguments must be NaN. | 85 // All comparisons failed, one of the arguments must be NaN. |
| 86 return NAN; | 86 return NAN; |
| 87 } | 87 } |
| 88 var r = -INFINITY; | 88 var r = -INFINITY; |
| 89 for (var i = 0; i < length; i++) { | 89 for (var i = 0; i < length; i++) { |
| 90 var n = %_Arguments(i); | 90 var n = %_Arguments(i); |
| 91 if (!IS_NUMBER(n)) n = NonNumberToNumber(n); | 91 n = TO_NUMBER_INLINE(n); |
| 92 // Make sure +0 is considered greater than -0. | 92 // Make sure +0 is considered greater than -0. |
| 93 if (NUMBER_IS_NAN(n) || n > r || (r === 0 && n === 0 && %_IsMinusZero(r))) { | 93 if (NUMBER_IS_NAN(n) || n > r || (r === 0 && n === 0 && %_IsMinusZero(r))) { |
| 94 r = n; | 94 r = n; |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 return r; | 97 return r; |
| 98 } | 98 } |
| 99 | 99 |
| 100 // ECMA 262 - 15.8.2.12 | 100 // ECMA 262 - 15.8.2.12 |
| 101 function MathMin(arg1, arg2) { // length == 2 | 101 function MathMin(arg1, arg2) { // length == 2 |
| 102 var length = %_ArgumentsLength(); | 102 var length = %_ArgumentsLength(); |
| 103 if (length == 2) { | 103 if (length == 2) { |
| 104 arg1 = TO_NUMBER_INLINE(arg1); | 104 arg1 = TO_NUMBER_INLINE(arg1); |
| 105 arg2 = TO_NUMBER_INLINE(arg2); | 105 arg2 = TO_NUMBER_INLINE(arg2); |
| 106 if (arg2 > arg1) return arg1; | 106 if (arg2 > arg1) return arg1; |
| 107 if (arg1 > arg2) return arg2; | 107 if (arg1 > arg2) return arg2; |
| 108 if (arg1 == arg2) { | 108 if (arg1 == arg2) { |
| 109 // Make sure -0 is considered less than +0. | 109 // Make sure -0 is considered less than +0. |
| 110 return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg1 : arg2; | 110 return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg1 : arg2; |
| 111 } | 111 } |
| 112 // All comparisons failed, one of the arguments must be NaN. | 112 // All comparisons failed, one of the arguments must be NaN. |
| 113 return NAN; | 113 return NAN; |
| 114 } | 114 } |
| 115 var r = INFINITY; | 115 var r = INFINITY; |
| 116 for (var i = 0; i < length; i++) { | 116 for (var i = 0; i < length; i++) { |
| 117 var n = %_Arguments(i); | 117 var n = %_Arguments(i); |
| 118 if (!IS_NUMBER(n)) n = NonNumberToNumber(n); | 118 n = TO_NUMBER_INLINE(n); |
| 119 // Make sure -0 is considered less than +0. | 119 // Make sure -0 is considered less than +0. |
| 120 if (NUMBER_IS_NAN(n) || n < r || (r === 0 && n === 0 && %_IsMinusZero(n))) { | 120 if (NUMBER_IS_NAN(n) || n < r || (r === 0 && n === 0 && %_IsMinusZero(n))) { |
| 121 r = n; | 121 r = n; |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 return r; | 124 return r; |
| 125 } | 125 } |
| 126 | 126 |
| 127 // ECMA 262 - 15.8.2.13 | 127 // ECMA 262 - 15.8.2.13 |
| 128 function MathPowJS(x, y) { | 128 function MathPowJS(x, y) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 function MathTrunc(x) { | 168 function MathTrunc(x) { |
| 169 x = +x; | 169 x = +x; |
| 170 if (x > 0) return %_MathFloor(x); | 170 if (x > 0) return %_MathFloor(x); |
| 171 if (x < 0) return -%_MathFloor(-x); | 171 if (x < 0) return -%_MathFloor(-x); |
| 172 // -0, 0 or NaN. | 172 // -0, 0 or NaN. |
| 173 return x; | 173 return x; |
| 174 } | 174 } |
| 175 | 175 |
| 176 // ES6 draft 09-27-13, section 20.2.2.33. | 176 // ES6 draft 09-27-13, section 20.2.2.33. |
| 177 function MathTanh(x) { | 177 function MathTanh(x) { |
| 178 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 178 x = TO_NUMBER_INLINE(x); |
| 179 // Idempotent for +/-0. | 179 // Idempotent for +/-0. |
| 180 if (x === 0) return x; | 180 if (x === 0) return x; |
| 181 // Returns +/-1 for +/-Infinity. | 181 // Returns +/-1 for +/-Infinity. |
| 182 if (!NUMBER_IS_FINITE(x)) return MathSign(x); | 182 if (!NUMBER_IS_FINITE(x)) return MathSign(x); |
| 183 var exp1 = MathExp(x); | 183 var exp1 = MathExp(x); |
| 184 var exp2 = MathExp(-x); | 184 var exp2 = MathExp(-x); |
| 185 return (exp1 - exp2) / (exp1 + exp2); | 185 return (exp1 - exp2) / (exp1 + exp2); |
| 186 } | 186 } |
| 187 | 187 |
| 188 // ES6 draft 09-27-13, section 20.2.2.5. | 188 // ES6 draft 09-27-13, section 20.2.2.5. |
| 189 function MathAsinh(x) { | 189 function MathAsinh(x) { |
| 190 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 190 x = TO_NUMBER_INLINE(x); |
| 191 // Idempotent for NaN, +/-0 and +/-Infinity. | 191 // Idempotent for NaN, +/-0 and +/-Infinity. |
| 192 if (x === 0 || !NUMBER_IS_FINITE(x)) return x; | 192 if (x === 0 || !NUMBER_IS_FINITE(x)) return x; |
| 193 if (x > 0) return MathLog(x + %_MathSqrt(x * x + 1)); | 193 if (x > 0) return MathLog(x + %_MathSqrt(x * x + 1)); |
| 194 // This is to prevent numerical errors caused by large negative x. | 194 // This is to prevent numerical errors caused by large negative x. |
| 195 return -MathLog(-x + %_MathSqrt(x * x + 1)); | 195 return -MathLog(-x + %_MathSqrt(x * x + 1)); |
| 196 } | 196 } |
| 197 | 197 |
| 198 // ES6 draft 09-27-13, section 20.2.2.3. | 198 // ES6 draft 09-27-13, section 20.2.2.3. |
| 199 function MathAcosh(x) { | 199 function MathAcosh(x) { |
| 200 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 200 x = TO_NUMBER_INLINE(x); |
| 201 if (x < 1) return NAN; | 201 if (x < 1) return NAN; |
| 202 // Idempotent for NaN and +Infinity. | 202 // Idempotent for NaN and +Infinity. |
| 203 if (!NUMBER_IS_FINITE(x)) return x; | 203 if (!NUMBER_IS_FINITE(x)) return x; |
| 204 return MathLog(x + %_MathSqrt(x + 1) * %_MathSqrt(x - 1)); | 204 return MathLog(x + %_MathSqrt(x + 1) * %_MathSqrt(x - 1)); |
| 205 } | 205 } |
| 206 | 206 |
| 207 // ES6 draft 09-27-13, section 20.2.2.7. | 207 // ES6 draft 09-27-13, section 20.2.2.7. |
| 208 function MathAtanh(x) { | 208 function MathAtanh(x) { |
| 209 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 209 x = TO_NUMBER_INLINE(x); |
| 210 // Idempotent for +/-0. | 210 // Idempotent for +/-0. |
| 211 if (x === 0) return x; | 211 if (x === 0) return x; |
| 212 // Returns NaN for NaN and +/- Infinity. | 212 // Returns NaN for NaN and +/- Infinity. |
| 213 if (!NUMBER_IS_FINITE(x)) return NAN; | 213 if (!NUMBER_IS_FINITE(x)) return NAN; |
| 214 return 0.5 * MathLog((1 + x) / (1 - x)); | 214 return 0.5 * MathLog((1 + x) / (1 - x)); |
| 215 } | 215 } |
| 216 | 216 |
| 217 // ES6 draft 09-27-13, section 20.2.2.17. | 217 // ES6 draft 09-27-13, section 20.2.2.17. |
| 218 function MathHypot(x, y) { // Function length is 2. | 218 function MathHypot(x, y) { // Function length is 2. |
| 219 // We may want to introduce fast paths for two arguments and when | 219 // We may want to introduce fast paths for two arguments and when |
| 220 // normalization to avoid overflow is not necessary. For now, we | 220 // normalization to avoid overflow is not necessary. For now, we |
| 221 // simply assume the general case. | 221 // simply assume the general case. |
| 222 var length = %_ArgumentsLength(); | 222 var length = %_ArgumentsLength(); |
| 223 var args = new InternalArray(length); | 223 var args = new InternalArray(length); |
| 224 var max = 0; | 224 var max = 0; |
| 225 for (var i = 0; i < length; i++) { | 225 for (var i = 0; i < length; i++) { |
| 226 var n = %_Arguments(i); | 226 var n = %_Arguments(i); |
| 227 if (!IS_NUMBER(n)) n = NonNumberToNumber(n); | 227 n = TO_NUMBER_INLINE(n); |
| 228 if (n === INFINITY || n === -INFINITY) return INFINITY; | 228 if (n === INFINITY || n === -INFINITY) return INFINITY; |
| 229 n = MathAbs(n); | 229 n = MathAbs(n); |
| 230 if (n > max) max = n; | 230 if (n > max) max = n; |
| 231 args[i] = n; | 231 args[i] = n; |
| 232 } | 232 } |
| 233 | 233 |
| 234 // Kahan summation to avoid rounding errors. | 234 // Kahan summation to avoid rounding errors. |
| 235 // Normalize the numbers to the largest one to avoid overflow. | 235 // Normalize the numbers to the largest one to avoid overflow. |
| 236 if (max === 0) max = 1; | 236 if (max === 0) max = 1; |
| 237 var sum = 0; | 237 var sum = 0; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 254 // ES6 draft 07-18-14, section 20.2.2.11 | 254 // ES6 draft 07-18-14, section 20.2.2.11 |
| 255 function MathClz32JS(x) { | 255 function MathClz32JS(x) { |
| 256 return %_MathClz32(x >>> 0); | 256 return %_MathClz32(x >>> 0); |
| 257 } | 257 } |
| 258 | 258 |
| 259 // ES6 draft 09-27-13, section 20.2.2.9. | 259 // ES6 draft 09-27-13, section 20.2.2.9. |
| 260 // Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm | 260 // Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm |
| 261 // Using initial approximation adapted from Kahan's cbrt and 4 iterations | 261 // Using initial approximation adapted from Kahan's cbrt and 4 iterations |
| 262 // of Newton's method. | 262 // of Newton's method. |
| 263 function MathCbrt(x) { | 263 function MathCbrt(x) { |
| 264 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 264 x = TO_NUMBER_INLINE(x); |
| 265 if (x == 0 || !NUMBER_IS_FINITE(x)) return x; | 265 if (x == 0 || !NUMBER_IS_FINITE(x)) return x; |
| 266 return x >= 0 ? CubeRoot(x) : -CubeRoot(-x); | 266 return x >= 0 ? CubeRoot(x) : -CubeRoot(-x); |
| 267 } | 267 } |
| 268 | 268 |
| 269 macro NEWTON_ITERATION_CBRT(x, approx) | 269 macro NEWTON_ITERATION_CBRT(x, approx) |
| 270 (1.0 / 3.0) * (x / (approx * approx) + 2 * approx); | 270 (1.0 / 3.0) * (x / (approx * approx) + 2 * approx); |
| 271 endmacro | 271 endmacro |
| 272 | 272 |
| 273 function CubeRoot(x) { | 273 function CubeRoot(x) { |
| 274 var approx_hi = MathFloorJS(%_DoubleHi(x) / 3) + 0x2A9F7893; | 274 var approx_hi = MathFloorJS(%_DoubleHi(x) / 3) + 0x2A9F7893; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 %SetInlineBuiltinFlag(MathTrunc); | 354 %SetInlineBuiltinFlag(MathTrunc); |
| 355 | 355 |
| 356 // Expose to the global scope. | 356 // Expose to the global scope. |
| 357 $abs = MathAbs; | 357 $abs = MathAbs; |
| 358 $exp = MathExp; | 358 $exp = MathExp; |
| 359 $floor = MathFloorJS; | 359 $floor = MathFloorJS; |
| 360 $max = MathMax; | 360 $max = MathMax; |
| 361 $min = MathMin; | 361 $min = MathMin; |
| 362 | 362 |
| 363 })(); | 363 })(); |
| OLD | NEW |