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

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

Issue 2063693002: [builtins] Introduce proper Float64Log2 and Float64Log10 operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: More precise log10. 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 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 })
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