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