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 |