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 "use strict"; | 5 "use strict"; |
6 | 6 |
7 // This file relies on the fact that the following declarations have been made | 7 // This file relies on the fact that the following declarations have been made |
8 // in runtime.js: | 8 // in runtime.js: |
9 // var $Object = global.Object; | 9 // var $Object = global.Object; |
10 | 10 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 // ToNumber (valueOf) is called. | 49 // ToNumber (valueOf) is called. |
50 function MathAtan2JS(y, x) { | 50 function MathAtan2JS(y, x) { |
51 return %MathAtan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x)); | 51 return %MathAtan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x)); |
52 } | 52 } |
53 | 53 |
54 // ECMA 262 - 15.8.2.6 | 54 // ECMA 262 - 15.8.2.6 |
55 function MathCeil(x) { | 55 function MathCeil(x) { |
56 return -MathFloor(-x); | 56 return -MathFloor(-x); |
57 } | 57 } |
58 | 58 |
59 // ECMA 262 - 15.8.2.7 | |
60 function MathCos(x) { | |
61 x = MathAbs(x); // Convert to number and get rid of -0. | |
62 return TrigonometricInterpolation(x, 1); | |
63 } | |
64 | |
65 // ECMA 262 - 15.8.2.8 | 59 // ECMA 262 - 15.8.2.8 |
66 function MathExp(x) { | 60 function MathExp(x) { |
67 return %MathExpRT(TO_NUMBER_INLINE(x)); | 61 return %MathExpRT(TO_NUMBER_INLINE(x)); |
68 } | 62 } |
69 | 63 |
70 // ECMA 262 - 15.8.2.9 | 64 // ECMA 262 - 15.8.2.9 |
71 function MathFloor(x) { | 65 function MathFloor(x) { |
72 x = TO_NUMBER_INLINE(x); | 66 x = TO_NUMBER_INLINE(x); |
73 // It's more common to call this with a positive number that's out | 67 // It's more common to call this with a positive number that's out |
74 // of range than negative numbers; check the upper bound first. | 68 // of range than negative numbers; check the upper bound first. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 var x = ((r0 << 16) + (r1 & 0xFFFF)) | 0; | 151 var x = ((r0 << 16) + (r1 & 0xFFFF)) | 0; |
158 // Division by 0x100000000 through multiplication by reciprocal. | 152 // Division by 0x100000000 through multiplication by reciprocal. |
159 return (x < 0 ? (x + 0x100000000) : x) * 2.3283064365386962890625e-10; | 153 return (x < 0 ? (x + 0x100000000) : x) * 2.3283064365386962890625e-10; |
160 } | 154 } |
161 | 155 |
162 // ECMA 262 - 15.8.2.15 | 156 // ECMA 262 - 15.8.2.15 |
163 function MathRound(x) { | 157 function MathRound(x) { |
164 return %RoundNumber(TO_NUMBER_INLINE(x)); | 158 return %RoundNumber(TO_NUMBER_INLINE(x)); |
165 } | 159 } |
166 | 160 |
167 // ECMA 262 - 15.8.2.16 | |
168 function MathSin(x) { | |
169 x = x * 1; // Convert to number and deal with -0. | |
170 if (%_IsMinusZero(x)) return x; | |
171 return TrigonometricInterpolation(x, 0); | |
172 } | |
173 | |
174 // ECMA 262 - 15.8.2.17 | 161 // ECMA 262 - 15.8.2.17 |
175 function MathSqrt(x) { | 162 function MathSqrt(x) { |
176 return %_MathSqrtRT(TO_NUMBER_INLINE(x)); | 163 return %_MathSqrtRT(TO_NUMBER_INLINE(x)); |
177 } | 164 } |
178 | 165 |
179 // ECMA 262 - 15.8.2.18 | |
180 function MathTan(x) { | |
181 return MathSin(x) / MathCos(x); | |
182 } | |
183 | |
184 // Non-standard extension. | 166 // Non-standard extension. |
185 function MathImul(x, y) { | 167 function MathImul(x, y) { |
186 return %NumberImul(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y)); | 168 return %NumberImul(TO_NUMBER_INLINE(x), TO_NUMBER_INLINE(y)); |
187 } | 169 } |
188 | 170 |
189 | |
190 var kInversePiHalf = 0.636619772367581343; // 2 / pi | |
191 var kInversePiHalfS26 = 9.48637384723993156e-9; // 2 / pi / (2^26) | |
192 var kS26 = 1 << 26; | |
193 var kTwoStepThreshold = 1 << 27; | |
194 // pi / 2 rounded up | |
195 var kPiHalf = 1.570796326794896780; // 0x192d4454fb21f93f | |
196 // We use two parts for pi/2 to emulate a higher precision. | |
197 // pi_half_1 only has 26 significant bits for mantissa. | |
198 // Note that pi_half > pi_half_1 + pi_half_2 | |
199 var kPiHalf1 = 1.570796325802803040; // 0x00000054fb21f93f | |
200 var kPiHalf2 = 9.920935796805404252e-10; // 0x3326a611460b113e | |
201 | |
202 var kSamples; // Initialized to a number during genesis. | |
203 var kIndexConvert; // Initialized to kSamples / (pi/2) during genesis. | |
204 var kSinTable; // Initialized to a Float64Array during genesis. | |
205 var kCosXIntervalTable; // Initialized to a Float64Array during genesis. | |
206 | |
207 // This implements sine using the following algorithm. | |
208 // 1) Multiplication takes care of to-number conversion. | |
209 // 2) Reduce x to the first quadrant [0, pi/2]. | |
210 // Conveniently enough, in case of +/-Infinity, we get NaN. | |
211 // Note that we try to use only 26 instead of 52 significant bits for | |
212 // mantissa to avoid rounding errors when multiplying. For very large | |
213 // input we therefore have additional steps. | |
214 // 3) Replace x by (pi/2-x) if x was in the 2nd or 4th quadrant. | |
215 // 4) Do a table lookup for the closest samples to the left and right of x. | |
216 // 5) Find the derivatives at those sampling points by table lookup: | |
217 // dsin(x)/dx = cos(x) = sin(pi/2-x) for x in [0, pi/2]. | |
218 // 6) Use cubic spline interpolation to approximate sin(x). | |
219 // 7) Negate the result if x was in the 3rd or 4th quadrant. | |
220 // 8) Get rid of -0 by adding 0. | |
221 function TrigonometricInterpolation(x, phase) { | |
222 if (x < 0 || x > kPiHalf) { | |
223 var multiple; | |
224 while (x < -kTwoStepThreshold || x > kTwoStepThreshold) { | |
225 // Let's assume this loop does not terminate. | |
226 // All numbers x in each loop forms a set S. | |
227 // (1) abs(x) > 2^27 for all x in S. | |
228 // (2) abs(multiple) != 0 since (2^27 * inverse_pi_half_s26) > 1 | |
229 // (3) multiple is rounded down in 2^26 steps, so the rounding error is | |
230 // at most max(ulp, 2^26). | |
231 // (4) so for x > 2^27, we subtract at most (1+pi/4)x and at least | |
232 // (1-pi/4)x | |
233 // (5) The subtraction results in x' so that abs(x') <= abs(x)*pi/4. | |
234 // Note that this difference cannot be simply rounded off. | |
235 // Set S cannot exist since (5) violates (1). Loop must terminate. | |
236 multiple = MathFloor(x * kInversePiHalfS26) * kS26; | |
237 x = x - multiple * kPiHalf1 - multiple * kPiHalf2; | |
238 } | |
239 multiple = MathFloor(x * kInversePiHalf); | |
240 x = x - multiple * kPiHalf1 - multiple * kPiHalf2; | |
241 phase += multiple; | |
242 } | |
243 var double_index = x * kIndexConvert; | |
244 if (phase & 1) double_index = kSamples - double_index; | |
245 var index = double_index | 0; | |
246 var t1 = double_index - index; | |
247 var t2 = 1 - t1; | |
248 var y1 = kSinTable[index]; | |
249 var y2 = kSinTable[index + 1]; | |
250 var dy = y2 - y1; | |
251 return (t2 * y1 + t1 * y2 + | |
252 t1 * t2 * ((kCosXIntervalTable[index] - dy) * t2 + | |
253 (dy - kCosXIntervalTable[index + 1]) * t1)) | |
254 * (1 - (phase & 2)) + 0; | |
255 } | |
256 | |
257 | |
258 // ES6 draft 09-27-13, section 20.2.2.28. | 171 // ES6 draft 09-27-13, section 20.2.2.28. |
259 function MathSign(x) { | 172 function MathSign(x) { |
260 x = TO_NUMBER_INLINE(x); | 173 x = TO_NUMBER_INLINE(x); |
261 if (x > 0) return 1; | 174 if (x > 0) return 1; |
262 if (x < 0) return -1; | 175 if (x < 0) return -1; |
263 if (x === 0) return x; | 176 if (x === 0) return x; |
264 return NAN; | 177 return NAN; |
265 } | 178 } |
266 | 179 |
267 | |
268 // ES6 draft 09-27-13, section 20.2.2.34. | 180 // ES6 draft 09-27-13, section 20.2.2.34. |
269 function MathTrunc(x) { | 181 function MathTrunc(x) { |
270 x = TO_NUMBER_INLINE(x); | 182 x = TO_NUMBER_INLINE(x); |
271 if (x > 0) return MathFloor(x); | 183 if (x > 0) return MathFloor(x); |
272 if (x < 0) return MathCeil(x); | 184 if (x < 0) return MathCeil(x); |
273 if (x === 0) return x; | 185 if (x === 0) return x; |
274 return NAN; | 186 return NAN; |
275 } | 187 } |
276 | 188 |
277 | |
278 // ES6 draft 09-27-13, section 20.2.2.30. | 189 // ES6 draft 09-27-13, section 20.2.2.30. |
279 function MathSinh(x) { | 190 function MathSinh(x) { |
280 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 191 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
281 // Idempotent for NaN, +/-0 and +/-Infinity. | 192 // Idempotent for NaN, +/-0 and +/-Infinity. |
282 if (x === 0 || !NUMBER_IS_FINITE(x)) return x; | 193 if (x === 0 || !NUMBER_IS_FINITE(x)) return x; |
283 return (MathExp(x) - MathExp(-x)) / 2; | 194 return (MathExp(x) - MathExp(-x)) / 2; |
284 } | 195 } |
285 | 196 |
286 | |
287 // ES6 draft 09-27-13, section 20.2.2.12. | 197 // ES6 draft 09-27-13, section 20.2.2.12. |
288 function MathCosh(x) { | 198 function MathCosh(x) { |
289 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 199 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
290 if (!NUMBER_IS_FINITE(x)) return MathAbs(x); | 200 if (!NUMBER_IS_FINITE(x)) return MathAbs(x); |
291 return (MathExp(x) + MathExp(-x)) / 2; | 201 return (MathExp(x) + MathExp(-x)) / 2; |
292 } | 202 } |
293 | 203 |
294 | |
295 // ES6 draft 09-27-13, section 20.2.2.33. | 204 // ES6 draft 09-27-13, section 20.2.2.33. |
296 function MathTanh(x) { | 205 function MathTanh(x) { |
297 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 206 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
298 // Idempotent for +/-0. | 207 // Idempotent for +/-0. |
299 if (x === 0) return x; | 208 if (x === 0) return x; |
300 // Returns +/-1 for +/-Infinity. | 209 // Returns +/-1 for +/-Infinity. |
301 if (!NUMBER_IS_FINITE(x)) return MathSign(x); | 210 if (!NUMBER_IS_FINITE(x)) return MathSign(x); |
302 var exp1 = MathExp(x); | 211 var exp1 = MathExp(x); |
303 var exp2 = MathExp(-x); | 212 var exp2 = MathExp(-x); |
304 return (exp1 - exp2) / (exp1 + exp2); | 213 return (exp1 - exp2) / (exp1 + exp2); |
305 } | 214 } |
306 | 215 |
307 | |
308 // ES6 draft 09-27-13, section 20.2.2.5. | 216 // ES6 draft 09-27-13, section 20.2.2.5. |
309 function MathAsinh(x) { | 217 function MathAsinh(x) { |
310 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 218 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
311 // Idempotent for NaN, +/-0 and +/-Infinity. | 219 // Idempotent for NaN, +/-0 and +/-Infinity. |
312 if (x === 0 || !NUMBER_IS_FINITE(x)) return x; | 220 if (x === 0 || !NUMBER_IS_FINITE(x)) return x; |
313 if (x > 0) return MathLog(x + MathSqrt(x * x + 1)); | 221 if (x > 0) return MathLog(x + MathSqrt(x * x + 1)); |
314 // This is to prevent numerical errors caused by large negative x. | 222 // This is to prevent numerical errors caused by large negative x. |
315 return -MathLog(-x + MathSqrt(x * x + 1)); | 223 return -MathLog(-x + MathSqrt(x * x + 1)); |
316 } | 224 } |
317 | 225 |
318 | |
319 // ES6 draft 09-27-13, section 20.2.2.3. | 226 // ES6 draft 09-27-13, section 20.2.2.3. |
320 function MathAcosh(x) { | 227 function MathAcosh(x) { |
321 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 228 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
322 if (x < 1) return NAN; | 229 if (x < 1) return NAN; |
323 // Idempotent for NaN and +Infinity. | 230 // Idempotent for NaN and +Infinity. |
324 if (!NUMBER_IS_FINITE(x)) return x; | 231 if (!NUMBER_IS_FINITE(x)) return x; |
325 return MathLog(x + MathSqrt(x + 1) * MathSqrt(x - 1)); | 232 return MathLog(x + MathSqrt(x + 1) * MathSqrt(x - 1)); |
326 } | 233 } |
327 | 234 |
328 | |
329 // ES6 draft 09-27-13, section 20.2.2.7. | 235 // ES6 draft 09-27-13, section 20.2.2.7. |
330 function MathAtanh(x) { | 236 function MathAtanh(x) { |
331 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 237 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
332 // Idempotent for +/-0. | 238 // Idempotent for +/-0. |
333 if (x === 0) return x; | 239 if (x === 0) return x; |
334 // Returns NaN for NaN and +/- Infinity. | 240 // Returns NaN for NaN and +/- Infinity. |
335 if (!NUMBER_IS_FINITE(x)) return NAN; | 241 if (!NUMBER_IS_FINITE(x)) return NAN; |
336 return 0.5 * MathLog((1 + x) / (1 - x)); | 242 return 0.5 * MathLog((1 + x) / (1 - x)); |
337 } | 243 } |
338 | 244 |
339 | |
340 // ES6 draft 09-27-13, section 20.2.2.21. | 245 // ES6 draft 09-27-13, section 20.2.2.21. |
341 function MathLog10(x) { | 246 function MathLog10(x) { |
342 return MathLog(x) * 0.434294481903251828; // log10(x) = log(x)/log(10). | 247 return MathLog(x) * 0.434294481903251828; // log10(x) = log(x)/log(10). |
343 } | 248 } |
344 | 249 |
345 | 250 |
346 // ES6 draft 09-27-13, section 20.2.2.22. | 251 // ES6 draft 09-27-13, section 20.2.2.22. |
347 function MathLog2(x) { | 252 function MathLog2(x) { |
348 return MathLog(x) * 1.442695040888963407; // log2(x) = log(x)/log(2). | 253 return MathLog(x) * 1.442695040888963407; // log2(x) = log(x)/log(2). |
349 } | 254 } |
350 | 255 |
351 | |
352 // ES6 draft 09-27-13, section 20.2.2.17. | 256 // ES6 draft 09-27-13, section 20.2.2.17. |
353 function MathHypot(x, y) { // Function length is 2. | 257 function MathHypot(x, y) { // Function length is 2. |
354 // We may want to introduce fast paths for two arguments and when | 258 // We may want to introduce fast paths for two arguments and when |
355 // normalization to avoid overflow is not necessary. For now, we | 259 // normalization to avoid overflow is not necessary. For now, we |
356 // simply assume the general case. | 260 // simply assume the general case. |
357 var length = %_ArgumentsLength(); | 261 var length = %_ArgumentsLength(); |
358 var args = new InternalArray(length); | 262 var args = new InternalArray(length); |
359 var max = 0; | 263 var max = 0; |
360 for (var i = 0; i < length; i++) { | 264 for (var i = 0; i < length; i++) { |
361 var n = %_Arguments(i); | 265 var n = %_Arguments(i); |
(...skipping 12 matching lines...) Expand all Loading... |
374 for (var i = 0; i < length; i++) { | 278 for (var i = 0; i < length; i++) { |
375 var n = args[i] / max; | 279 var n = args[i] / max; |
376 var summand = n * n - compensation; | 280 var summand = n * n - compensation; |
377 var preliminary = sum + summand; | 281 var preliminary = sum + summand; |
378 compensation = (preliminary - sum) - summand; | 282 compensation = (preliminary - sum) - summand; |
379 sum = preliminary; | 283 sum = preliminary; |
380 } | 284 } |
381 return MathSqrt(sum) * max; | 285 return MathSqrt(sum) * max; |
382 } | 286 } |
383 | 287 |
384 | |
385 // ES6 draft 09-27-13, section 20.2.2.16. | 288 // ES6 draft 09-27-13, section 20.2.2.16. |
386 function MathFroundJS(x) { | 289 function MathFroundJS(x) { |
387 return %MathFround(TO_NUMBER_INLINE(x)); | 290 return %MathFround(TO_NUMBER_INLINE(x)); |
388 } | 291 } |
389 | 292 |
390 | 293 // ES6 draft 07-18-14, section 20.2.2.11 |
391 function MathClz32(x) { | 294 function MathClz32(x) { |
392 x = ToUint32(TO_NUMBER_INLINE(x)); | 295 x = ToUint32(TO_NUMBER_INLINE(x)); |
393 if (x == 0) return 32; | 296 if (x == 0) return 32; |
394 var result = 0; | 297 var result = 0; |
395 // Binary search. | 298 // Binary search. |
396 if ((x & 0xFFFF0000) === 0) { x <<= 16; result += 16; }; | 299 if ((x & 0xFFFF0000) === 0) { x <<= 16; result += 16; }; |
397 if ((x & 0xFF000000) === 0) { x <<= 8; result += 8; }; | 300 if ((x & 0xFF000000) === 0) { x <<= 8; result += 8; }; |
398 if ((x & 0xF0000000) === 0) { x <<= 4; result += 4; }; | 301 if ((x & 0xF0000000) === 0) { x <<= 4; result += 4; }; |
399 if ((x & 0xC0000000) === 0) { x <<= 2; result += 2; }; | 302 if ((x & 0xC0000000) === 0) { x <<= 2; result += 2; }; |
400 if ((x & 0x80000000) === 0) { x <<= 1; result += 1; }; | 303 if ((x & 0x80000000) === 0) { x <<= 1; result += 1; }; |
401 return result; | 304 return result; |
402 } | 305 } |
403 | 306 |
404 | |
405 // ES6 draft 09-27-13, section 20.2.2.9. | 307 // ES6 draft 09-27-13, section 20.2.2.9. |
406 // Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm | 308 // Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm |
407 // Using initial approximation adapted from Kahan's cbrt and 4 iterations | 309 // Using initial approximation adapted from Kahan's cbrt and 4 iterations |
408 // of Newton's method. | 310 // of Newton's method. |
409 function MathCbrt(x) { | 311 function MathCbrt(x) { |
410 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 312 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
411 if (x == 0 || !NUMBER_IS_FINITE(x)) return x; | 313 if (x == 0 || !NUMBER_IS_FINITE(x)) return x; |
412 return x >= 0 ? CubeRoot(x) : -CubeRoot(-x); | 314 return x >= 0 ? CubeRoot(x) : -CubeRoot(-x); |
413 } | 315 } |
414 | 316 |
415 macro NEWTON_ITERATION_CBRT(x, approx) | 317 macro NEWTON_ITERATION_CBRT(x, approx) |
416 (1.0 / 3.0) * (x / (approx * approx) + 2 * approx); | 318 (1.0 / 3.0) * (x / (approx * approx) + 2 * approx); |
417 endmacro | 319 endmacro |
418 | 320 |
419 function CubeRoot(x) { | 321 function CubeRoot(x) { |
420 var approx_hi = MathFloor(%_DoubleHi(x) / 3) + 0x2A9F7893; | 322 var approx_hi = MathFloor(%_DoubleHi(x) / 3) + 0x2A9F7893; |
421 var approx = %_ConstructDouble(approx_hi, 0); | 323 var approx = %_ConstructDouble(approx_hi, 0); |
422 approx = NEWTON_ITERATION_CBRT(x, approx); | 324 approx = NEWTON_ITERATION_CBRT(x, approx); |
423 approx = NEWTON_ITERATION_CBRT(x, approx); | 325 approx = NEWTON_ITERATION_CBRT(x, approx); |
424 approx = NEWTON_ITERATION_CBRT(x, approx); | 326 approx = NEWTON_ITERATION_CBRT(x, approx); |
425 return NEWTON_ITERATION_CBRT(x, approx); | 327 return NEWTON_ITERATION_CBRT(x, approx); |
426 } | 328 } |
427 | 329 |
428 | |
429 | |
430 // ES6 draft 09-27-13, section 20.2.2.14. | 330 // ES6 draft 09-27-13, section 20.2.2.14. |
431 // Use Taylor series to approximate. | 331 // Use Taylor series to approximate. |
432 // exp(x) - 1 at 0 == -1 + exp(0) + exp'(0)*x/1! + exp''(0)*x^2/2! + ... | 332 // exp(x) - 1 at 0 == -1 + exp(0) + exp'(0)*x/1! + exp''(0)*x^2/2! + ... |
433 // == x/1! + x^2/2! + x^3/3! + ... | 333 // == x/1! + x^2/2! + x^3/3! + ... |
434 // The closer x is to 0, the fewer terms are required. | 334 // The closer x is to 0, the fewer terms are required. |
435 function MathExpm1(x) { | 335 function MathExpm1(x) { |
436 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 336 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
437 var xabs = MathAbs(x); | 337 var xabs = MathAbs(x); |
438 if (xabs < 2E-7) { | 338 if (xabs < 2E-7) { |
439 return x * (1 + x * (1/2)); | 339 return x * (1 + x * (1/2)); |
440 } else if (xabs < 6E-5) { | 340 } else if (xabs < 6E-5) { |
441 return x * (1 + x * (1/2 + x * (1/6))); | 341 return x * (1 + x * (1/2 + x * (1/6))); |
442 } else if (xabs < 2E-2) { | 342 } else if (xabs < 2E-2) { |
443 return x * (1 + x * (1/2 + x * (1/6 + | 343 return x * (1 + x * (1/2 + x * (1/6 + |
444 x * (1/24 + x * (1/120 + x * (1/720)))))); | 344 x * (1/24 + x * (1/120 + x * (1/720)))))); |
445 } else { // Use regular exp if not close enough to 0. | 345 } else { // Use regular exp if not close enough to 0. |
446 return MathExp(x) - 1; | 346 return MathExp(x) - 1; |
447 } | 347 } |
448 } | 348 } |
449 | 349 |
450 | |
451 // ES6 draft 09-27-13, section 20.2.2.20. | 350 // ES6 draft 09-27-13, section 20.2.2.20. |
452 // Use Taylor series to approximate. With y = x + 1; | 351 // Use Taylor series to approximate. With y = x + 1; |
453 // log(y) at 1 == log(1) + log'(1)(y-1)/1! + log''(1)(y-1)^2/2! + ... | 352 // log(y) at 1 == log(1) + log'(1)(y-1)/1! + log''(1)(y-1)^2/2! + ... |
454 // == 0 + x - x^2/2 + x^3/3 ... | 353 // == 0 + x - x^2/2 + x^3/3 ... |
455 // The closer x is to 0, the fewer terms are required. | 354 // The closer x is to 0, the fewer terms are required. |
456 function MathLog1p(x) { | 355 function MathLog1p(x) { |
457 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); | 356 if (!IS_NUMBER(x)) x = NonNumberToNumber(x); |
458 var xabs = MathAbs(x); | 357 var xabs = MathAbs(x); |
459 if (xabs < 1E-7) { | 358 if (xabs < 1E-7) { |
460 return x * (1 - x * (1/2)); | 359 return x * (1 - x * (1/2)); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 | 394 |
496 // Set up non-enumerable functions of the Math object and | 395 // Set up non-enumerable functions of the Math object and |
497 // set their names. | 396 // set their names. |
498 InstallFunctions($Math, DONT_ENUM, $Array( | 397 InstallFunctions($Math, DONT_ENUM, $Array( |
499 "random", MathRandom, | 398 "random", MathRandom, |
500 "abs", MathAbs, | 399 "abs", MathAbs, |
501 "acos", MathAcosJS, | 400 "acos", MathAcosJS, |
502 "asin", MathAsinJS, | 401 "asin", MathAsinJS, |
503 "atan", MathAtanJS, | 402 "atan", MathAtanJS, |
504 "ceil", MathCeil, | 403 "ceil", MathCeil, |
505 "cos", MathCos, | 404 "cos", MathCos, // implemented by third_party/fdlibm |
506 "exp", MathExp, | 405 "exp", MathExp, |
507 "floor", MathFloor, | 406 "floor", MathFloor, |
508 "log", MathLog, | 407 "log", MathLog, |
509 "round", MathRound, | 408 "round", MathRound, |
510 "sin", MathSin, | 409 "sin", MathSin, // implemented by third_party/fdlibm |
511 "sqrt", MathSqrt, | 410 "sqrt", MathSqrt, |
512 "tan", MathTan, | 411 "tan", MathTan, // implemented by third_party/fdlibm |
513 "atan2", MathAtan2JS, | 412 "atan2", MathAtan2JS, |
514 "pow", MathPow, | 413 "pow", MathPow, |
515 "max", MathMax, | 414 "max", MathMax, |
516 "min", MathMin, | 415 "min", MathMin, |
517 "imul", MathImul, | 416 "imul", MathImul, |
518 "sign", MathSign, | 417 "sign", MathSign, |
519 "trunc", MathTrunc, | 418 "trunc", MathTrunc, |
520 "sinh", MathSinh, | 419 "sinh", MathSinh, |
521 "cosh", MathCosh, | 420 "cosh", MathCosh, |
522 "tanh", MathTanh, | 421 "tanh", MathTanh, |
523 "asinh", MathAsinh, | 422 "asinh", MathAsinh, |
524 "acosh", MathAcosh, | 423 "acosh", MathAcosh, |
525 "atanh", MathAtanh, | 424 "atanh", MathAtanh, |
526 "log10", MathLog10, | 425 "log10", MathLog10, |
527 "log2", MathLog2, | 426 "log2", MathLog2, |
528 "hypot", MathHypot, | 427 "hypot", MathHypot, |
529 "fround", MathFroundJS, | 428 "fround", MathFroundJS, |
530 "clz32", MathClz32, | 429 "clz32", MathClz32, |
531 "cbrt", MathCbrt, | 430 "cbrt", MathCbrt, |
532 "log1p", MathLog1p, | 431 "log1p", MathLog1p, |
533 "expm1", MathExpm1 | 432 "expm1", MathExpm1 |
534 )); | 433 )); |
535 | 434 |
536 %SetInlineBuiltinFlag(MathCeil); | 435 %SetInlineBuiltinFlag(MathCeil); |
537 %SetInlineBuiltinFlag(MathRandom); | 436 %SetInlineBuiltinFlag(MathRandom); |
538 %SetInlineBuiltinFlag(MathSin); | 437 %SetInlineBuiltinFlag(MathSin); |
539 %SetInlineBuiltinFlag(MathCos); | 438 %SetInlineBuiltinFlag(MathCos); |
540 %SetInlineBuiltinFlag(MathTan); | |
541 %SetInlineBuiltinFlag(TrigonometricInterpolation); | |
542 } | 439 } |
543 | 440 |
544 SetUpMath(); | 441 SetUpMath(); |
OLD | NEW |