| 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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 var t = MathExpm1(-2 * ax); | 750 var t = MathExpm1(-2 * ax); |
| 751 z = -t / (t + 2); | 751 z = -t / (t + 2); |
| 752 } | 752 } |
| 753 } else { | 753 } else { |
| 754 // |x| > 22, return +/- 1 | 754 // |x| > 22, return +/- 1 |
| 755 z = 1; | 755 z = 1; |
| 756 } | 756 } |
| 757 return (x >= 0) ? z : -z; | 757 return (x >= 0) ? z : -z; |
| 758 } | 758 } |
| 759 | 759 |
| 760 // ES6 draft 09-27-13, section 20.2.2.21. | |
| 761 // Return the base 10 logarithm of x | |
| 762 // | |
| 763 // Method : | |
| 764 // Let log10_2hi = leading 40 bits of log10(2) and | |
| 765 // log10_2lo = log10(2) - log10_2hi, | |
| 766 // ivln10 = 1/log(10) rounded. | |
| 767 // Then | |
| 768 // n = ilogb(x), | |
| 769 // if(n<0) n = n+1; | |
| 770 // x = scalbn(x,-n); | |
| 771 // log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) | |
| 772 // | |
| 773 // Note 1: | |
| 774 // To guarantee log10(10**n)=n, where 10**n is normal, the rounding | |
| 775 // mode must set to Round-to-Nearest. | |
| 776 // Note 2: | |
| 777 // [1/log(10)] rounded to 53 bits has error .198 ulps; | |
| 778 // log10 is monotonic at all binary break points. | |
| 779 // | |
| 780 // Special cases: | |
| 781 // log10(x) is NaN if x < 0; | |
| 782 // log10(+INF) is +INF; log10(0) is -INF; | |
| 783 // log10(NaN) is that NaN; | |
| 784 // log10(10**N) = N for N=0,1,...,22. | |
| 785 // | |
| 786 | |
| 787 define IVLN10 = 4.34294481903251816668e-01; | |
| 788 define LOG10_2HI = 3.01029995663611771306e-01; | |
| 789 define LOG10_2LO = 3.69423907715893078616e-13; | |
| 790 | |
| 791 function MathLog10(x) { | |
| 792 x = x * 1; // Convert to number. | |
| 793 var hx = %_DoubleHi(x); | |
| 794 var lx = %_DoubleLo(x); | |
| 795 var k = 0; | |
| 796 | |
| 797 if (hx < 0x00100000) { | |
| 798 // x < 2^-1022 | |
| 799 // log10(+/- 0) = -Infinity. | |
| 800 if (((hx & 0x7fffffff) | lx) === 0) return -INFINITY; | |
| 801 // log10 of negative number is NaN. | |
| 802 if (hx < 0) return NaN; | |
| 803 // Subnormal number. Scale up x. | |
| 804 k -= 54; | |
| 805 x *= TWO54; | |
| 806 hx = %_DoubleHi(x); | |
| 807 lx = %_DoubleLo(x); | |
| 808 } | |
| 809 | |
| 810 // Infinity or NaN. | |
| 811 if (hx >= 0x7ff00000) return x; | |
| 812 | |
| 813 k += (hx >> 20) - 1023; | |
| 814 var i = (k & 0x80000000) >>> 31; | |
| 815 hx = (hx & 0x000fffff) | ((0x3ff - i) << 20); | |
| 816 var y = k + i; | |
| 817 x = %_ConstructDouble(hx, lx); | |
| 818 | |
| 819 var z = y * LOG10_2LO + IVLN10 * %math_log(x); | |
| 820 return z + y * LOG10_2HI; | |
| 821 } | |
| 822 | |
| 823 | |
| 824 // ES6 draft 09-27-13, section 20.2.2.22. | |
| 825 // Return the base 2 logarithm of x | |
| 826 // | |
| 827 // fdlibm does not have an explicit log2 function, but fdlibm's pow | |
| 828 // function does implement an accurate log2 function as part of the | |
| 829 // pow implementation. This extracts the core parts of that as a | |
| 830 // separate log2 function. | |
| 831 | |
| 832 // Method: | |
| 833 // Compute log2(x) in two pieces: | |
| 834 // log2(x) = w1 + w2 | |
| 835 // where w1 has 53-24 = 29 bits of trailing zeroes. | |
| 836 | |
| 837 define DP_H = 5.84962487220764160156e-01; | |
| 838 define DP_L = 1.35003920212974897128e-08; | |
| 839 | |
| 840 // Polynomial coefficients for (3/2)*(log2(x) - 2*s - 2/3*s^3) | |
| 841 define LOG2_1 = 5.99999999999994648725e-01; | |
| 842 define LOG2_2 = 4.28571428578550184252e-01; | |
| 843 define LOG2_3 = 3.33333329818377432918e-01; | |
| 844 define LOG2_4 = 2.72728123808534006489e-01; | |
| 845 define LOG2_5 = 2.30660745775561754067e-01; | |
| 846 define LOG2_6 = 2.06975017800338417784e-01; | |
| 847 | |
| 848 // cp = 2/(3*ln(2)). Note that cp_h + cp_l is cp, but with more accuracy. | |
| 849 define CP = 9.61796693925975554329e-01; | |
| 850 define CP_H = 9.61796700954437255859e-01; | |
| 851 define CP_L = -7.02846165095275826516e-09; | |
| 852 // 2^53 | |
| 853 define TWO53 = 9007199254740992; | |
| 854 | |
| 855 function MathLog2(x) { | |
| 856 x = x * 1; // Convert to number. | |
| 857 var ax = MathAbs(x); | |
| 858 var hx = %_DoubleHi(x); | |
| 859 var lx = %_DoubleLo(x); | |
| 860 var ix = hx & 0x7fffffff; | |
| 861 | |
| 862 // Handle special cases. | |
| 863 // log2(+/- 0) = -Infinity | |
| 864 if ((ix | lx) == 0) return -INFINITY; | |
| 865 | |
| 866 // log(x) = NaN, if x < 0 | |
| 867 if (hx < 0) return NaN; | |
| 868 | |
| 869 // log2(Infinity) = Infinity, log2(NaN) = NaN | |
| 870 if (ix >= 0x7ff00000) return x; | |
| 871 | |
| 872 var n = 0; | |
| 873 | |
| 874 // Take care of subnormal number. | |
| 875 if (ix < 0x00100000) { | |
| 876 ax *= TWO53; | |
| 877 n -= 53; | |
| 878 ix = %_DoubleHi(ax); | |
| 879 } | |
| 880 | |
| 881 n += (ix >> 20) - 0x3ff; | |
| 882 var j = ix & 0x000fffff; | |
| 883 | |
| 884 // Determine interval. | |
| 885 ix = j | 0x3ff00000; // normalize ix. | |
| 886 | |
| 887 var bp = 1; | |
| 888 var dp_h = 0; | |
| 889 var dp_l = 0; | |
| 890 if (j > 0x3988e) { // |x| > sqrt(3/2) | |
| 891 if (j < 0xbb67a) { // |x| < sqrt(3) | |
| 892 bp = 1.5; | |
| 893 dp_h = DP_H; | |
| 894 dp_l = DP_L; | |
| 895 } else { | |
| 896 n += 1; | |
| 897 ix -= 0x00100000; | |
| 898 } | |
| 899 } | |
| 900 | |
| 901 ax = %_ConstructDouble(ix, %_DoubleLo(ax)); | |
| 902 | |
| 903 // Compute ss = s_h + s_l = (x - 1)/(x+1) or (x - 1.5)/(x + 1.5) | |
| 904 var u = ax - bp; | |
| 905 var v = 1 / (ax + bp); | |
| 906 var ss = u * v; | |
| 907 var s_h = %_ConstructDouble(%_DoubleHi(ss), 0); | |
| 908 | |
| 909 // t_h = ax + bp[k] High | |
| 910 var t_h = %_ConstructDouble(%_DoubleHi(ax + bp), 0) | |
| 911 var t_l = ax - (t_h - bp); | |
| 912 var s_l = v * ((u - s_h * t_h) - s_h * t_l); | |
| 913 | |
| 914 // Compute log2(ax) | |
| 915 var s2 = ss * ss; | |
| 916 var r = s2 * s2 * (LOG2_1 + s2 * (LOG2_2 + s2 * (LOG2_3 + s2 * ( | |
| 917 LOG2_4 + s2 * (LOG2_5 + s2 * LOG2_6))))); | |
| 918 r += s_l * (s_h + ss); | |
| 919 s2 = s_h * s_h; | |
| 920 t_h = %_ConstructDouble(%_DoubleHi(3.0 + s2 + r), 0); | |
| 921 t_l = r - ((t_h - 3.0) - s2); | |
| 922 // u + v = ss * (1 + ...) | |
| 923 u = s_h * t_h; | |
| 924 v = s_l * t_h + t_l * ss; | |
| 925 | |
| 926 // 2 / (3 * log(2)) * (ss + ...) | |
| 927 var p_h = %_ConstructDouble(%_DoubleHi(u + v), 0); | |
| 928 var p_l = v - (p_h - u); | |
| 929 var z_h = CP_H * p_h; | |
| 930 var z_l = CP_L * p_h + p_l * CP + dp_l; | |
| 931 | |
| 932 // log2(ax) = (ss + ...) * 2 / (3 * log(2)) = n + dp_h + z_h + z_l | |
| 933 var t = n; | |
| 934 var t1 = %_ConstructDouble(%_DoubleHi(((z_h + z_l) + dp_h) + t), 0); | |
| 935 var t2 = z_l - (((t1 - t) - dp_h) - z_h); | |
| 936 | |
| 937 // t1 + t2 = log2(ax), sum up because we do not care about extra precision. | |
| 938 return t1 + t2; | |
| 939 } | |
| 940 | |
| 941 //------------------------------------------------------------------- | 760 //------------------------------------------------------------------- |
| 942 | 761 |
| 943 utils.InstallFunctions(GlobalMath, DONT_ENUM, [ | 762 utils.InstallFunctions(GlobalMath, DONT_ENUM, [ |
| 944 "cos", MathCos, | 763 "cos", MathCos, |
| 945 "sin", MathSin, | 764 "sin", MathSin, |
| 946 "tan", MathTan, | 765 "tan", MathTan, |
| 947 "sinh", MathSinh, | 766 "sinh", MathSinh, |
| 948 "cosh", MathCosh, | 767 "cosh", MathCosh, |
| 949 "tanh", MathTanh, | 768 "tanh", MathTanh, |
| 950 "log10", MathLog10, | |
| 951 "log2", MathLog2, | |
| 952 "expm1", MathExpm1 | 769 "expm1", MathExpm1 |
| 953 ]); | 770 ]); |
| 954 | 771 |
| 955 %SetForceInlineFlag(MathSin); | 772 %SetForceInlineFlag(MathSin); |
| 956 %SetForceInlineFlag(MathCos); | 773 %SetForceInlineFlag(MathCos); |
| 957 | 774 |
| 958 }) | 775 }) |
| OLD | NEW |