Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: src/third_party/fdlibm/fdlibm.js

Issue 2068743002: [builtins] Unify Atanh, Cbrt and Expm1 as exports from flibm. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixed type warning. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | test/cctest/compiler/test-run-machops.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
24 "use strict"; 24 "use strict";
25 25
26 %CheckIsBootstrapping(); 26 %CheckIsBootstrapping();
27 27
28 // ------------------------------------------------------------------- 28 // -------------------------------------------------------------------
29 // Imports 29 // Imports
30 30
31 var GlobalFloat64Array = global.Float64Array; 31 var GlobalFloat64Array = global.Float64Array;
32 var GlobalMath = global.Math; 32 var GlobalMath = global.Math;
33 var MathAbs; 33 var MathAbs;
34 var MathExpm1;
34 var NaN = %GetRootNaN(); 35 var NaN = %GetRootNaN();
35 var rempio2result; 36 var rempio2result;
36 37
37 utils.Import(function(from) { 38 utils.Import(function(from) {
38 MathAbs = from.MathAbs; 39 MathAbs = from.MathAbs;
40 MathExpm1 = from.MathExpm1;
39 }); 41 });
40 42
41 utils.CreateDoubleResultArray = function(global) { 43 utils.CreateDoubleResultArray = function(global) {
42 rempio2result = new GlobalFloat64Array(2); 44 rempio2result = new GlobalFloat64Array(2);
43 }; 45 };
44 46
45 // ------------------------------------------------------------------- 47 // -------------------------------------------------------------------
46 48
47 define INVPIO2 = 6.36619772367581382433e-01; 49 define INVPIO2 = 6.36619772367581382433e-01;
48 define PIO2_1 = 1.57079632673412561417; 50 define PIO2_1 = 1.57079632673412561417;
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 REMPIO2(x); 396 REMPIO2(x);
395 return KernelTan(y0, y1, (n & 1) ? -1 : 1); 397 return KernelTan(y0, y1, (n & 1) ? -1 : 1);
396 } 398 }
397 399
398 define LN2_HI = 6.93147180369123816490e-01; 400 define LN2_HI = 6.93147180369123816490e-01;
399 define LN2_LO = 1.90821492927058770002e-10; 401 define LN2_LO = 1.90821492927058770002e-10;
400 402
401 // 2^54 403 // 2^54
402 define TWO54 = 18014398509481984; 404 define TWO54 = 18014398509481984;
403 405
404 // ES6 draft 09-27-13, section 20.2.2.14.
405 // Math.expm1
406 // Returns exp(x)-1, the exponential of x minus 1.
407 //
408 // Method
409 // 1. Argument reduction:
410 // Given x, find r and integer k such that
411 //
412 // x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
413 //
414 // Here a correction term c will be computed to compensate
415 // the error in r when rounded to a floating-point number.
416 //
417 // 2. Approximating expm1(r) by a special rational function on
418 // the interval [0,0.34658]:
419 // Since
420 // r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
421 // we define R1(r*r) by
422 // r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
423 // That is,
424 // R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
425 // = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
426 // = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
427 // We use a special Remes algorithm on [0,0.347] to generate
428 // a polynomial of degree 5 in r*r to approximate R1. The
429 // maximum error of this polynomial approximation is bounded
430 // by 2**-61. In other words,
431 // R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
432 // where Q1 = -1.6666666666666567384E-2,
433 // Q2 = 3.9682539681370365873E-4,
434 // Q3 = -9.9206344733435987357E-6,
435 // Q4 = 2.5051361420808517002E-7,
436 // Q5 = -6.2843505682382617102E-9;
437 // (where z=r*r, and the values of Q1 to Q5 are listed below)
438 // with error bounded by
439 // | 5 | -61
440 // | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
441 // | |
442 //
443 // expm1(r) = exp(r)-1 is then computed by the following
444 // specific way which minimize the accumulation rounding error:
445 // 2 3
446 // r r [ 3 - (R1 + R1*r/2) ]
447 // expm1(r) = r + --- + --- * [--------------------]
448 // 2 2 [ 6 - r*(3 - R1*r/2) ]
449 //
450 // To compensate the error in the argument reduction, we use
451 // expm1(r+c) = expm1(r) + c + expm1(r)*c
452 // ~ expm1(r) + c + r*c
453 // Thus c+r*c will be added in as the correction terms for
454 // expm1(r+c). Now rearrange the term to avoid optimization
455 // screw up:
456 // ( 2 2 )
457 // ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
458 // expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
459 // ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
460 // ( )
461 //
462 // = r - E
463 // 3. Scale back to obtain expm1(x):
464 // From step 1, we have
465 // expm1(x) = either 2^k*[expm1(r)+1] - 1
466 // = or 2^k*[expm1(r) + (1-2^-k)]
467 // 4. Implementation notes:
468 // (A). To save one multiplication, we scale the coefficient Qi
469 // to Qi*2^i, and replace z by (x^2)/2.
470 // (B). To achieve maximum accuracy, we compute expm1(x) by
471 // (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
472 // (ii) if k=0, return r-E
473 // (iii) if k=-1, return 0.5*(r-E)-0.5
474 // (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
475 // else return 1.0+2.0*(r-E);
476 // (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
477 // (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
478 // (vii) return 2^k(1-((E+2^-k)-r))
479 //
480 // Special cases:
481 // expm1(INF) is INF, expm1(NaN) is NaN;
482 // expm1(-INF) is -1, and
483 // for finite argument, only expm1(0)=0 is exact.
484 //
485 // Accuracy:
486 // according to an error analysis, the error is always less than
487 // 1 ulp (unit in the last place).
488 //
489 // Misc. info.
490 // For IEEE double
491 // if x > 7.09782712893383973096e+02 then expm1(x) overflow
492 //
493 define KEXPM1_OVERFLOW = 7.09782712893383973096e+02;
494 define INVLN2 = 1.44269504088896338700;
495 define EXPM1_1 = -3.33333333333331316428e-02;
496 define EXPM1_2 = 1.58730158725481460165e-03;
497 define EXPM1_3 = -7.93650757867487942473e-05;
498 define EXPM1_4 = 4.00821782732936239552e-06;
499 define EXPM1_5 = -2.01099218183624371326e-07;
500
501 function MathExpm1(x) {
502 x = x * 1; // Convert to number.
503 var y;
504 var hi;
505 var lo;
506 var k;
507 var t;
508 var c;
509
510 var hx = %_DoubleHi(x);
511 var xsb = hx & 0x80000000; // Sign bit of x
512 var y = (xsb === 0) ? x : -x; // y = |x|
513 hx &= 0x7fffffff; // High word of |x|
514
515 // Filter out huge and non-finite argument
516 if (hx >= 0x4043687a) { // if |x| ~=> 56 * ln2
517 if (hx >= 0x40862e42) { // if |x| >= 709.78
518 if (hx >= 0x7ff00000) {
519 // expm1(inf) = inf; expm1(-inf) = -1; expm1(nan) = nan;
520 return (x === -INFINITY) ? -1 : x;
521 }
522 if (x > KEXPM1_OVERFLOW) return INFINITY; // Overflow
523 }
524 if (xsb != 0) return -1; // x < -56 * ln2, return -1.
525 }
526
527 // Argument reduction
528 if (hx > 0x3fd62e42) { // if |x| > 0.5 * ln2
529 if (hx < 0x3ff0a2b2) { // and |x| < 1.5 * ln2
530 if (xsb === 0) {
531 hi = x - LN2_HI;
532 lo = LN2_LO;
533 k = 1;
534 } else {
535 hi = x + LN2_HI;
536 lo = -LN2_LO;
537 k = -1;
538 }
539 } else {
540 k = (INVLN2 * x + ((xsb === 0) ? 0.5 : -0.5)) | 0;
541 t = k;
542 // t * ln2_hi is exact here.
543 hi = x - t * LN2_HI;
544 lo = t * LN2_LO;
545 }
546 x = hi - lo;
547 c = (hi - x) - lo;
548 } else if (hx < 0x3c900000) {
549 // When |x| < 2^-54, we can return x.
550 return x;
551 } else {
552 // Fall through.
553 k = 0;
554 }
555
556 // x is now in primary range
557 var hfx = 0.5 * x;
558 var hxs = x * hfx;
559 var r1 = 1 + hxs * (EXPM1_1 + hxs * (EXPM1_2 + hxs *
560 (EXPM1_3 + hxs * (EXPM1_4 + hxs * EXPM1_5))));
561 t = 3 - r1 * hfx;
562 var e = hxs * ((r1 - t) / (6 - x * t));
563 if (k === 0) { // c is 0
564 return x - (x*e - hxs);
565 } else {
566 e = (x * (e - c) - c);
567 e -= hxs;
568 if (k === -1) return 0.5 * (x - e) - 0.5;
569 if (k === 1) {
570 if (x < -0.25) return -2 * (e - (x + 0.5));
571 return 1 + 2 * (x - e);
572 }
573
574 if (k <= -2 || k > 56) {
575 // suffice to return exp(x) + 1
576 y = 1 - (e - x);
577 // Add k to y's exponent
578 y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
579 return y - 1;
580 }
581 if (k < 20) {
582 // t = 1 - 2^k
583 t = %_ConstructDouble(0x3ff00000 - (0x200000 >> k), 0);
584 y = t - (e - x);
585 // Add k to y's exponent
586 y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
587 } else {
588 // t = 2^-k
589 t = %_ConstructDouble((0x3ff - k) << 20, 0);
590 y = x - (e + t);
591 y += 1;
592 // Add k to y's exponent
593 y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
594 }
595 }
596 return y;
597 }
598
599
600 // ES6 draft 09-27-13, section 20.2.2.30. 406 // ES6 draft 09-27-13, section 20.2.2.30.
601 // Math.sinh 407 // Math.sinh
602 // Method : 408 // Method :
603 // mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 409 // mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
604 // 1. Replace x by |x| (sinh(-x) = -sinh(x)). 410 // 1. Replace x by |x| (sinh(-x) = -sinh(x)).
605 // 2. 411 // 2.
606 // E + E/(E+1) 412 // E + E/(E+1)
607 // 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) 413 // 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x)
608 // 2 414 // 2
609 // 415 //
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 } 562 }
757 563
758 //------------------------------------------------------------------- 564 //-------------------------------------------------------------------
759 565
760 utils.InstallFunctions(GlobalMath, DONT_ENUM, [ 566 utils.InstallFunctions(GlobalMath, DONT_ENUM, [
761 "cos", MathCos, 567 "cos", MathCos,
762 "sin", MathSin, 568 "sin", MathSin,
763 "tan", MathTan, 569 "tan", MathTan,
764 "sinh", MathSinh, 570 "sinh", MathSinh,
765 "cosh", MathCosh, 571 "cosh", MathCosh,
766 "tanh", MathTanh, 572 "tanh", MathTanh
767 "expm1", MathExpm1
768 ]); 573 ]);
769 574
770 %SetForceInlineFlag(MathSin); 575 %SetForceInlineFlag(MathSin);
771 %SetForceInlineFlag(MathCos); 576 %SetForceInlineFlag(MathCos);
772 577
773 }) 578 })
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/cctest/compiler/test-run-machops.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698