| 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 // ==================================================== |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 var w = x + y; | 260 var w = x + y; |
| 261 var z = %_ConstructDouble(%_DoubleHi(w), 0); | 261 var z = %_ConstructDouble(%_DoubleHi(w), 0); |
| 262 var v = y - (z - x); | 262 var v = y - (z - x); |
| 263 var a = -1 / w; | 263 var a = -1 / w; |
| 264 var t = %_ConstructDouble(%_DoubleHi(a), 0); | 264 var t = %_ConstructDouble(%_DoubleHi(a), 0); |
| 265 var s = 1 + t * z; | 265 var s = 1 + t * z; |
| 266 return t + a * (s + t * v); | 266 return t + a * (s + t * v); |
| 267 } | 267 } |
| 268 } | 268 } |
| 269 } | 269 } |
| 270 if (ix >= 0x3fe59429) { // |x| > .6744 | 270 if (ix >= 0x3fe59428) { // |x| > .6744 |
| 271 if (x < 0) { | 271 if (x < 0) { |
| 272 x = -x; | 272 x = -x; |
| 273 y = -y; | 273 y = -y; |
| 274 } | 274 } |
| 275 z = PIO4 - x; | 275 z = PIO4 - x; |
| 276 w = PIO4LO - y; | 276 w = PIO4LO - y; |
| 277 x = z + w; | 277 x = z + w; |
| 278 y = 0; | 278 y = 0; |
| 279 } | 279 } |
| 280 z = x * x; | 280 z = x * x; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 355 // |x| < pi/4, approximately. No reduction needed. | 355 // |x| < pi/4, approximately. No reduction needed. |
| 356 return KernelTan(x, 0, 1); | 356 return KernelTan(x, 0, 1); |
| 357 } | 357 } |
| 358 REMPIO2(x); | 358 REMPIO2(x); |
| 359 return KernelTan(y0, y1, (n & 1) ? -1 : 1); | 359 return KernelTan(y0, y1, (n & 1) ? -1 : 1); |
| 360 } | 360 } |
| 361 | 361 |
| 362 // ES6 draft 09-27-13, section 20.2.2.20. | 362 // ES6 draft 09-27-13, section 20.2.2.20. |
| 363 // Math.log1p | 363 // Math.log1p |
| 364 // | 364 // |
| 365 // Method : | 365 // Method : |
| 366 // 1. Argument Reduction: find k and f such that | 366 // 1. Argument Reduction: find k and f such that |
| 367 // 1+x = 2^k * (1+f), | 367 // 1+x = 2^k * (1+f), |
| 368 // where sqrt(2)/2 < 1+f < sqrt(2) . | 368 // where sqrt(2)/2 < 1+f < sqrt(2) . |
| 369 // | 369 // |
| 370 // Note. If k=0, then f=x is exact. However, if k!=0, then f | 370 // Note. If k=0, then f=x is exact. However, if k!=0, then f |
| 371 // may not be representable exactly. In that case, a correction | 371 // may not be representable exactly. In that case, a correction |
| 372 // term is need. Let u=1+x rounded. Let c = (1+x)-u, then | 372 // term is need. Let u=1+x rounded. Let c = (1+x)-u, then |
| 373 // log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), | 373 // log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), |
| 374 // and add back the correction term c/u. | 374 // and add back the correction term c/u. |
| 375 // (Note: when x > 2**53, one can simply return log(x)) | 375 // (Note: when x > 2**53, one can simply return log(x)) |
| 376 // | 376 // |
| 377 // 2. Approximation of log1p(f). | 377 // 2. Approximation of log1p(f). |
| 378 // Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) | 378 // Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) |
| 379 // = 2s + 2/3 s**3 + 2/5 s**5 + ....., | 379 // = 2s + 2/3 s**3 + 2/5 s**5 + ....., |
| 380 // = 2s + s*R | 380 // = 2s + s*R |
| 381 // We use a special Reme algorithm on [0,0.1716] to generate | 381 // We use a special Reme algorithm on [0,0.1716] to generate |
| 382 // a polynomial of degree 14 to approximate R The maximum error | 382 // a polynomial of degree 14 to approximate R The maximum error |
| 383 // of this polynomial approximation is bounded by 2**-58.45. In | 383 // of this polynomial approximation is bounded by 2**-58.45. In |
| 384 // other words, | 384 // other words, |
| 385 // 2 4 6 8 10 12 14 | 385 // 2 4 6 8 10 12 14 |
| 386 // R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s | 386 // R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s |
| 387 // (the values of Lp1 to Lp7 are listed in the program) | 387 // (the values of Lp1 to Lp7 are listed in the program) |
| 388 // and | 388 // and |
| 389 // | 2 14 | -58.45 | 389 // | 2 14 | -58.45 |
| 390 // | Lp1*s +...+Lp7*s - R(z) | <= 2 | 390 // | Lp1*s +...+Lp7*s - R(z) | <= 2 |
| 391 // | | | 391 // | | |
| 392 // Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. | 392 // Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. |
| 393 // In order to guarantee error in log below 1ulp, we compute log | 393 // In order to guarantee error in log below 1ulp, we compute log |
| 394 // by | 394 // by |
| 395 // log1p(f) = f - (hfsq - s*(hfsq+R)). | 395 // log1p(f) = f - (hfsq - s*(hfsq+R)). |
| 396 // | 396 // |
| 397 // 3. Finally, log1p(x) = k*ln2 + log1p(f). | 397 // 3. Finally, log1p(x) = k*ln2 + log1p(f). |
| 398 // = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) | 398 // = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) |
| 399 // Here ln2 is split into two floating point number: | 399 // Here ln2 is split into two floating point number: |
| 400 // ln2_hi + ln2_lo, | 400 // ln2_hi + ln2_lo, |
| 401 // where n*ln2_hi is always exact for |n| < 2000. | 401 // where n*ln2_hi is always exact for |n| < 2000. |
| 402 // | 402 // |
| 403 // Special cases: | 403 // Special cases: |
| 404 // log1p(x) is NaN with signal if x < -1 (including -INF) ; | 404 // log1p(x) is NaN with signal if x < -1 (including -INF) ; |
| 405 // log1p(+INF) is +INF; log1p(-1) is -INF with signal; | 405 // log1p(+INF) is +INF; log1p(-1) is -INF with signal; |
| 406 // log1p(NaN) is that NaN with no signal. | 406 // log1p(NaN) is that NaN with no signal. |
| 407 // | 407 // |
| 408 // Accuracy: | 408 // Accuracy: |
| 409 // according to an error analysis, the error is always less than | 409 // according to an error analysis, the error is always less than |
| 410 // 1 ulp (unit in the last place). | 410 // 1 ulp (unit in the last place). |
| 411 // | 411 // |
| 412 // Constants: | 412 // Constants: |
| 413 // Constants are found in fdlibm.cc. We assume the C++ compiler to convert | 413 // Constants are found in fdlibm.cc. We assume the C++ compiler to convert |
| 414 // from decimal to binary accurately enough to produce the intended values. | 414 // from decimal to binary accurately enough to produce the intended values. |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 } | 499 } |
| 500 } | 500 } |
| 501 var R = hfsq * (1 - TWO_THIRD * f); | 501 var R = hfsq * (1 - TWO_THIRD * f); |
| 502 if (k === 0) { | 502 if (k === 0) { |
| 503 return f - R; | 503 return f - R; |
| 504 } else { | 504 } else { |
| 505 return k * LN2_HI - ((R - (k * LN2_LO + c)) - f); | 505 return k * LN2_HI - ((R - (k * LN2_LO + c)) - f); |
| 506 } | 506 } |
| 507 } | 507 } |
| 508 | 508 |
| 509 var s = f / (2 + f); | 509 var s = f / (2 + f); |
| 510 var z = s * s; | 510 var z = s * s; |
| 511 var R = z * (KLOG1P(0) + z * (KLOG1P(1) + z * | 511 var R = z * (KLOG1P(0) + z * (KLOG1P(1) + z * |
| 512 (KLOG1P(2) + z * (KLOG1P(3) + z * | 512 (KLOG1P(2) + z * (KLOG1P(3) + z * |
| 513 (KLOG1P(4) + z * (KLOG1P(5) + z * KLOG1P(6))))))); | 513 (KLOG1P(4) + z * (KLOG1P(5) + z * KLOG1P(6))))))); |
| 514 if (k === 0) { | 514 if (k === 0) { |
| 515 return f - (hfsq - s * (hfsq + R)); | 515 return f - (hfsq - s * (hfsq + R)); |
| 516 } else { | 516 } else { |
| 517 return k * LN2_HI - ((hfsq - (s * (hfsq + R) + (k * LN2_LO + c))) - f); | 517 return k * LN2_HI - ((hfsq - (s * (hfsq + R) + (k * LN2_LO + c))) - f); |
| 518 } | 518 } |
| 519 } | 519 } |
| 520 | 520 |
| 521 // ES6 draft 09-27-13, section 20.2.2.14. | 521 // ES6 draft 09-27-13, section 20.2.2.14. |
| 522 // Math.expm1 | 522 // Math.expm1 |
| 523 // Returns exp(x)-1, the exponential of x minus 1. | 523 // Returns exp(x)-1, the exponential of x minus 1. |
| 524 // | 524 // |
| 525 // Method | 525 // Method |
| 526 // 1. Argument reduction: | 526 // 1. Argument reduction: |
| 527 // Given x, find r and integer k such that | 527 // Given x, find r and integer k such that |
| 528 // | 528 // |
| 529 // x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 | 529 // x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 |
| 530 // | 530 // |
| 531 // Here a correction term c will be computed to compensate | 531 // Here a correction term c will be computed to compensate |
| 532 // the error in r when rounded to a floating-point number. | 532 // the error in r when rounded to a floating-point number. |
| 533 // | 533 // |
| 534 // 2. Approximating expm1(r) by a special rational function on | 534 // 2. Approximating expm1(r) by a special rational function on |
| 535 // the interval [0,0.34658]: | 535 // the interval [0,0.34658]: |
| 536 // Since | 536 // Since |
| 537 // r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... | 537 // r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... |
| 538 // we define R1(r*r) by | 538 // we define R1(r*r) by |
| 539 // r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) | 539 // r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) |
| 540 // That is, | 540 // That is, |
| 541 // R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) | 541 // R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) |
| 542 // = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) | 542 // = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) |
| 543 // = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... | 543 // = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... |
| 544 // We use a special Remes algorithm on [0,0.347] to generate | 544 // We use a special Remes algorithm on [0,0.347] to generate |
| 545 // a polynomial of degree 5 in r*r to approximate R1. The | 545 // a polynomial of degree 5 in r*r to approximate R1. The |
| 546 // maximum error of this polynomial approximation is bounded | 546 // maximum error of this polynomial approximation is bounded |
| 547 // by 2**-61. In other words, | 547 // by 2**-61. In other words, |
| 548 // R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 | 548 // R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 |
| 549 // where Q1 = -1.6666666666666567384E-2, | 549 // where Q1 = -1.6666666666666567384E-2, |
| 550 // Q2 = 3.9682539681370365873E-4, | 550 // Q2 = 3.9682539681370365873E-4, |
| 551 // Q3 = -9.9206344733435987357E-6, | 551 // Q3 = -9.9206344733435987357E-6, |
| 552 // Q4 = 2.5051361420808517002E-7, | 552 // Q4 = 2.5051361420808517002E-7, |
| 553 // Q5 = -6.2843505682382617102E-9; | 553 // Q5 = -6.2843505682382617102E-9; |
| 554 // (where z=r*r, and the values of Q1 to Q5 are listed below) | 554 // (where z=r*r, and the values of Q1 to Q5 are listed below) |
| 555 // with error bounded by | 555 // with error bounded by |
| 556 // | 5 | -61 | 556 // | 5 | -61 |
| 557 // | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 | 557 // | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 |
| 558 // | | | 558 // | | |
| 559 // | 559 // |
| 560 // expm1(r) = exp(r)-1 is then computed by the following | 560 // expm1(r) = exp(r)-1 is then computed by the following |
| 561 // specific way which minimize the accumulation rounding error: | 561 // specific way which minimize the accumulation rounding error: |
| 562 // 2 3 | 562 // 2 3 |
| 563 // r r [ 3 - (R1 + R1*r/2) ] | 563 // r r [ 3 - (R1 + R1*r/2) ] |
| 564 // expm1(r) = r + --- + --- * [--------------------] | 564 // expm1(r) = r + --- + --- * [--------------------] |
| 565 // 2 2 [ 6 - r*(3 - R1*r/2) ] | 565 // 2 2 [ 6 - r*(3 - R1*r/2) ] |
| 566 // | 566 // |
| 567 // To compensate the error in the argument reduction, we use | 567 // To compensate the error in the argument reduction, we use |
| 568 // expm1(r+c) = expm1(r) + c + expm1(r)*c | 568 // expm1(r+c) = expm1(r) + c + expm1(r)*c |
| 569 // ~ expm1(r) + c + r*c | 569 // ~ expm1(r) + c + r*c |
| 570 // Thus c+r*c will be added in as the correction terms for | 570 // Thus c+r*c will be added in as the correction terms for |
| 571 // expm1(r+c). Now rearrange the term to avoid optimization | 571 // expm1(r+c). Now rearrange the term to avoid optimization |
| 572 // screw up: | 572 // screw up: |
| 573 // ( 2 2 ) | 573 // ( 2 2 ) |
| 574 // ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) | 574 // ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) |
| 575 // expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) | 575 // expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) |
| 576 // ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) | 576 // ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) |
| 577 // ( ) | 577 // ( ) |
| 578 // | 578 // |
| 579 // = r - E | 579 // = r - E |
| 580 // 3. Scale back to obtain expm1(x): | 580 // 3. Scale back to obtain expm1(x): |
| 581 // From step 1, we have | 581 // From step 1, we have |
| 582 // expm1(x) = either 2^k*[expm1(r)+1] - 1 | 582 // expm1(x) = either 2^k*[expm1(r)+1] - 1 |
| 583 // = or 2^k*[expm1(r) + (1-2^-k)] | 583 // = or 2^k*[expm1(r) + (1-2^-k)] |
| 584 // 4. Implementation notes: | 584 // 4. Implementation notes: |
| 585 // (A). To save one multiplication, we scale the coefficient Qi | 585 // (A). To save one multiplication, we scale the coefficient Qi |
| 586 // to Qi*2^i, and replace z by (x^2)/2. | 586 // to Qi*2^i, and replace z by (x^2)/2. |
| 587 // (B). To achieve maximum accuracy, we compute expm1(x) by | 587 // (B). To achieve maximum accuracy, we compute expm1(x) by |
| 588 // (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) | 588 // (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) |
| 589 // (ii) if k=0, return r-E | 589 // (ii) if k=0, return r-E |
| 590 // (iii) if k=-1, return 0.5*(r-E)-0.5 | 590 // (iii) if k=-1, return 0.5*(r-E)-0.5 |
| 591 // (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) | 591 // (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) |
| 592 // else return 1.0+2.0*(r-E); | 592 // else return 1.0+2.0*(r-E); |
| 593 // (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) | 593 // (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) |
| 594 // (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else | 594 // (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else |
| 595 // (vii) return 2^k(1-((E+2^-k)-r)) | 595 // (vii) return 2^k(1-((E+2^-k)-r)) |
| 596 // | 596 // |
| 597 // Special cases: | 597 // Special cases: |
| 598 // expm1(INF) is INF, expm1(NaN) is NaN; | 598 // expm1(INF) is INF, expm1(NaN) is NaN; |
| 599 // expm1(-INF) is -1, and | 599 // expm1(-INF) is -1, and |
| 600 // for finite argument, only expm1(0)=0 is exact. | 600 // for finite argument, only expm1(0)=0 is exact. |
| 601 // | 601 // |
| 602 // Accuracy: | 602 // Accuracy: |
| 603 // according to an error analysis, the error is always less than | 603 // according to an error analysis, the error is always less than |
| 604 // 1 ulp (unit in the last place). | 604 // 1 ulp (unit in the last place). |
| 605 // | 605 // |
| 606 // Misc. info. | 606 // Misc. info. |
| 607 // For IEEE double | 607 // For IEEE double |
| 608 // if x > 7.09782712893383973096e+02 then expm1(x) overflow | 608 // if x > 7.09782712893383973096e+02 then expm1(x) overflow |
| 609 // | 609 // |
| 610 const KEXPM1_OVERFLOW = kMath[45]; | 610 const KEXPM1_OVERFLOW = kMath[45]; |
| 611 const INVLN2 = kMath[46]; | 611 const INVLN2 = kMath[46]; |
| 612 macro KEXPM1(x) | 612 macro KEXPM1(x) |
| 613 (kMath[47+x]) | 613 (kMath[47+x]) |
| 614 endmacro | 614 endmacro |
| 615 | 615 |
| 616 function MathExpm1(x) { | 616 function MathExpm1(x) { |
| 617 x = x * 1; // Convert to number. | 617 x = x * 1; // Convert to number. |
| 618 var y; | 618 var y; |
| 619 var hi; | 619 var hi; |
| 620 var lo; | 620 var lo; |
| 621 var k; | 621 var k; |
| 622 var t; | 622 var t; |
| 623 var c; | 623 var c; |
| 624 | 624 |
| 625 var hx = %_DoubleHi(x); | 625 var hx = %_DoubleHi(x); |
| 626 var xsb = hx & 0x80000000; // Sign bit of x | 626 var xsb = hx & 0x80000000; // Sign bit of x |
| 627 var y = (xsb === 0) ? x : -x; // y = |x| | 627 var y = (xsb === 0) ? x : -x; // y = |x| |
| 628 hx &= 0x7fffffff; // High word of |x| | 628 hx &= 0x7fffffff; // High word of |x| |
| 629 | 629 |
| 630 // Filter out huge and non-finite argument | 630 // Filter out huge and non-finite argument |
| 631 if (hx >= 0x4043687a) { // if |x| ~=> 56 * ln2 | 631 if (hx >= 0x4043687a) { // if |x| ~=> 56 * ln2 |
| 632 if (hx >= 0x40862e42) { // if |x| >= 709.78 | 632 if (hx >= 0x40862e42) { // if |x| >= 709.78 |
| 633 if (hx >= 0x7ff00000) { | 633 if (hx >= 0x7ff00000) { |
| 634 // expm1(inf) = inf; expm1(-inf) = -1; expm1(nan) = nan; | 634 // expm1(inf) = inf; expm1(-inf) = -1; expm1(nan) = nan; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 // ES6 draft 09-27-13, section 20.2.2.30. | 715 // ES6 draft 09-27-13, section 20.2.2.30. |
| 716 // Math.sinh | 716 // Math.sinh |
| 717 // Method : | 717 // Method : |
| 718 // mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 | 718 // mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 |
| 719 // 1. Replace x by |x| (sinh(-x) = -sinh(x)). | 719 // 1. Replace x by |x| (sinh(-x) = -sinh(x)). |
| 720 // 2. | 720 // 2. |
| 721 // E + E/(E+1) | 721 // E + E/(E+1) |
| 722 // 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) | 722 // 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) |
| 723 // 2 | 723 // 2 |
| 724 // | 724 // |
| 725 // 22 <= x <= lnovft : sinh(x) := exp(x)/2 | 725 // 22 <= x <= lnovft : sinh(x) := exp(x)/2 |
| 726 // lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2) | 726 // lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2) |
| 727 // ln2ovft < x : sinh(x) := x*shuge (overflow) | 727 // ln2ovft < x : sinh(x) := x*shuge (overflow) |
| 728 // | 728 // |
| 729 // Special cases: | 729 // Special cases: |
| 730 // sinh(x) is |x| if x is +Infinity, -Infinity, or NaN. | 730 // sinh(x) is |x| if x is +Infinity, -Infinity, or NaN. |
| 731 // only sinh(0)=0 is exact for finite x. | 731 // only sinh(0)=0 is exact for finite x. |
| 732 // | 732 // |
| 733 const KSINH_OVERFLOW = kMath[52]; | 733 const KSINH_OVERFLOW = kMath[52]; |
| 734 const TWO_M28 = 3.725290298461914e-9; // 2^-28, empty lower half | 734 const TWO_M28 = 3.725290298461914e-9; // 2^-28, empty lower half |
| 735 const LOG_MAXD = 709.7822265625; // 0x40862e42 00000000, empty lower half | 735 const LOG_MAXD = 709.7822265625; // 0x40862e42 00000000, empty lower half |
| (...skipping 20 matching lines...) Expand all Loading... |
| 756 return t * w; | 756 return t * w; |
| 757 } | 757 } |
| 758 // |x| > overflowthreshold or is NaN. | 758 // |x| > overflowthreshold or is NaN. |
| 759 // Return Infinity of the appropriate sign or NaN. | 759 // Return Infinity of the appropriate sign or NaN. |
| 760 return x * INFINITY; | 760 return x * INFINITY; |
| 761 } | 761 } |
| 762 | 762 |
| 763 | 763 |
| 764 // ES6 draft 09-27-13, section 20.2.2.12. | 764 // ES6 draft 09-27-13, section 20.2.2.12. |
| 765 // Math.cosh | 765 // Math.cosh |
| 766 // Method : | 766 // Method : |
| 767 // mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 | 767 // mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 |
| 768 // 1. Replace x by |x| (cosh(x) = cosh(-x)). | 768 // 1. Replace x by |x| (cosh(x) = cosh(-x)). |
| 769 // 2. | 769 // 2. |
| 770 // [ exp(x) - 1 ]^2 | 770 // [ exp(x) - 1 ]^2 |
| 771 // 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- | 771 // 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- |
| 772 // 2*exp(x) | 772 // 2*exp(x) |
| 773 // | 773 // |
| 774 // exp(x) + 1/exp(x) | 774 // exp(x) + 1/exp(x) |
| 775 // ln2/2 <= x <= 22 : cosh(x) := ------------------- | 775 // ln2/2 <= x <= 22 : cosh(x) := ------------------- |
| 776 // 2 | 776 // 2 |
| 777 // 22 <= x <= lnovft : cosh(x) := exp(x)/2 | 777 // 22 <= x <= lnovft : cosh(x) := exp(x)/2 |
| 778 // lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) | 778 // lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) |
| 779 // ln2ovft < x : cosh(x) := huge*huge (overflow) | 779 // ln2ovft < x : cosh(x) := huge*huge (overflow) |
| 780 // | 780 // |
| 781 // Special cases: | 781 // Special cases: |
| 782 // cosh(x) is |x| if x is +INF, -INF, or NaN. | 782 // cosh(x) is |x| if x is +INF, -INF, or NaN. |
| 783 // only cosh(0)=1 is exact for finite x. | 783 // only cosh(0)=1 is exact for finite x. |
| 784 // | 784 // |
| 785 const KCOSH_OVERFLOW = kMath[52]; | 785 const KCOSH_OVERFLOW = kMath[52]; |
| 786 | 786 |
| 787 function MathCosh(x) { | 787 function MathCosh(x) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 805 // |x| in [log(maxdouble), overflowthreshold] | 805 // |x| in [log(maxdouble), overflowthreshold] |
| 806 if (MathAbs(x) <= KCOSH_OVERFLOW) { | 806 if (MathAbs(x) <= KCOSH_OVERFLOW) { |
| 807 var w = MathExp(0.5 * MathAbs(x)); | 807 var w = MathExp(0.5 * MathAbs(x)); |
| 808 var t = 0.5 * w; | 808 var t = 0.5 * w; |
| 809 return t * w; | 809 return t * w; |
| 810 } | 810 } |
| 811 if (NUMBER_IS_NAN(x)) return x; | 811 if (NUMBER_IS_NAN(x)) return x; |
| 812 // |x| > overflowthreshold. | 812 // |x| > overflowthreshold. |
| 813 return INFINITY; | 813 return INFINITY; |
| 814 } | 814 } |
| OLD | NEW |