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

Side by Side Diff: src/base/ieee754.cc

Issue 2083453002: [builtins] Introduce proper Float64Tan operator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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/base/ieee754.h ('k') | src/bootstrapper.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 by Sun Microsystems, Inc. All rights reserved. 4 // Copyright (C) 1993 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 743 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 z = x * x; 754 z = x * x;
755 v = z * x; 755 v = z * x;
756 r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6))); 756 r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6)));
757 if (iy == 0) { 757 if (iy == 0) {
758 return x + v * (S1 + z * r); 758 return x + v * (S1 + z * r);
759 } else { 759 } else {
760 return x - ((z * (half * y - v * r) - y) - v * S1); 760 return x - ((z * (half * y - v * r) - y) - v * S1);
761 } 761 }
762 } 762 }
763 763
764 /* __kernel_tan( x, y, k )
765 * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
766 * Input x is assumed to be bounded by ~pi/4 in magnitude.
767 * Input y is the tail of x.
768 * Input k indicates whether tan (if k=1) or
769 * -1/tan (if k= -1) is returned.
770 *
771 * Algorithm
772 * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
773 * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
774 * 3. tan(x) is approximated by a odd polynomial of degree 27 on
775 * [0,0.67434]
776 * 3 27
777 * tan(x) ~ x + T1*x + ... + T13*x
778 * where
779 *
780 * |tan(x) 2 4 26 | -59.2
781 * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
782 * | x |
783 *
784 * Note: tan(x+y) = tan(x) + tan'(x)*y
785 * ~ tan(x) + (1+x*x)*y
786 * Therefore, for better accuracy in computing tan(x+y), let
787 * 3 2 2 2 2
788 * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
789 * then
790 * 3 2
791 * tan(x+y) = x + (T1*x + (x *(r+y)+y))
792 *
793 * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
794 * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
795 * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
796 */
797 double __kernel_tan(double x, double y, int iy) {
798 static const double xxx[] = {
799 3.33333333333334091986e-01, /* 3FD55555, 55555563 */
800 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
801 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */
802 2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */
803 8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */
804 3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */
805 1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */
806 5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */
807 2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */
808 7.81794442939557092300e-05, /* 3F147E88, A03792A6 */
809 7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */
810 -1.85586374855275456654e-05, /* BEF375CB, DB605373 */
811 2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */
812 /* one */ 1.00000000000000000000e+00, /* 3FF00000, 00000000 */
813 /* pio4 */ 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
814 /* pio4lo */ 3.06161699786838301793e-17 /* 3C81A626, 33145C07 */
815 };
816 #define one xxx[13]
817 #define pio4 xxx[14]
818 #define pio4lo xxx[15]
819 #define T xxx
820
821 double z, r, v, w, s;
822 int32_t ix, hx;
823
824 GET_HIGH_WORD(hx, x); /* high word of x */
825 ix = hx & 0x7fffffff; /* high word of |x| */
826 if (ix < 0x3e300000) { /* x < 2**-28 */
827 if (static_cast<int>(x) == 0) { /* generate inexact */
828 u_int32_t low;
829 GET_LOW_WORD(low, x);
830 if (((ix | low) | (iy + 1)) == 0) {
831 return one / fabs(x);
832 } else {
833 if (iy == 1) {
834 return x;
835 } else { /* compute -1 / (x+y) carefully */
836 double a, t;
837
838 z = w = x + y;
839 SET_LOW_WORD(z, 0);
840 v = y - (z - x);
841 t = a = -one / w;
842 SET_LOW_WORD(t, 0);
843 s = one + t * z;
844 return t + a * (s + t * v);
845 }
846 }
847 }
848 }
849 if (ix >= 0x3FE59428) { /* |x| >= 0.6744 */
850 if (hx < 0) {
851 x = -x;
852 y = -y;
853 }
854 z = pio4 - x;
855 w = pio4lo - y;
856 x = z + w;
857 y = 0.0;
858 }
859 z = x * x;
860 w = z * z;
861 /*
862 * Break x^5*(T[1]+x^2*T[2]+...) into
863 * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
864 * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
865 */
866 r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + w * T[11]))));
867 v = z *
868 (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + w * T[12])))));
869 s = z * x;
870 r = y + z * (s * (r + v) + y);
871 r += T[0] * s;
872 w = x + r;
873 if (ix >= 0x3FE59428) {
874 v = iy;
875 return (1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - (w * w / (w + v) - r)));
876 }
877 if (iy == 1) {
878 return w;
879 } else {
880 /*
881 * if allow error up to 2 ulp, simply return
882 * -1.0 / (x+r) here
883 */
884 /* compute -1.0 / (x+r) accurately */
885 double a, t;
886 z = w;
887 SET_LOW_WORD(z, 0);
888 v = r - (z - x); /* z+v = r+x */
889 t = a = -1.0 / w; /* a = -1.0/w */
890 SET_LOW_WORD(t, 0);
891 s = 1.0 + t * z;
892 return t + a * (s + t * v);
893 }
894
895 #undef one
896 #undef pio4
897 #undef pio4lo
898 #undef T
899 }
900
764 } // namespace 901 } // namespace
765 902
766 /* atan(x) 903 /* atan(x)
767 * Method 904 * Method
768 * 1. Reduce x to positive by atan(x) = -atan(-x). 905 * 1. Reduce x to positive by atan(x) = -atan(-x).
769 * 2. According to the integer k=4t+0.25 chopped, t=x, the argument 906 * 2. According to the integer k=4t+0.25 chopped, t=x, the argument
770 * is further reduced to one of the following intervals and the 907 * is further reduced to one of the following intervals and the
771 * arctangent of t is evaluated by the corresponding formula: 908 * arctangent of t is evaluated by the corresponding formula:
772 * 909 *
773 * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) 910 * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
(...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 case 1: 2253 case 1:
2117 return __kernel_cos(y[0], y[1]); 2254 return __kernel_cos(y[0], y[1]);
2118 case 2: 2255 case 2:
2119 return -__kernel_sin(y[0], y[1], 1); 2256 return -__kernel_sin(y[0], y[1], 1);
2120 default: 2257 default:
2121 return -__kernel_cos(y[0], y[1]); 2258 return -__kernel_cos(y[0], y[1]);
2122 } 2259 }
2123 } 2260 }
2124 } 2261 }
2125 2262
2263 /* tan(x)
2264 * Return tangent function of x.
2265 *
2266 * kernel function:
2267 * __kernel_tan ... tangent function on [-pi/4,pi/4]
2268 * __ieee754_rem_pio2 ... argument reduction routine
2269 *
2270 * Method.
2271 * Let S,C and T denote the sin, cos and tan respectively on
2272 * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
2273 * in [-pi/4 , +pi/4], and let n = k mod 4.
2274 * We have
2275 *
2276 * n sin(x) cos(x) tan(x)
2277 * ----------------------------------------------------------
2278 * 0 S C T
2279 * 1 C -S -1/T
2280 * 2 -S -C T
2281 * 3 -C S -1/T
2282 * ----------------------------------------------------------
2283 *
2284 * Special cases:
2285 * Let trig be any of sin, cos, or tan.
2286 * trig(+-INF) is NaN, with signals;
2287 * trig(NaN) is that NaN;
2288 *
2289 * Accuracy:
2290 * TRIG(x) returns trig(x) nearly rounded
2291 */
2292 double tan(double x) {
2293 double y[2], z = 0.0;
2294 int32_t n, ix;
2295
2296 /* High word of x. */
2297 GET_HIGH_WORD(ix, x);
2298
2299 /* |x| ~< pi/4 */
2300 ix &= 0x7fffffff;
2301 if (ix <= 0x3fe921fb) {
2302 return __kernel_tan(x, z, 1);
2303 } else if (ix >= 0x7ff00000) {
2304 /* tan(Inf or NaN) is NaN */
2305 return x - x; /* NaN */
2306 } else {
2307 /* argument reduction needed */
2308 n = __ieee754_rem_pio2(x, y);
2309 /* 1 -> n even, -1 -> n odd */
2310 return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1));
2311 }
2312 }
2313
2126 } // namespace ieee754 2314 } // namespace ieee754
2127 } // namespace base 2315 } // namespace base
2128 } // namespace v8 2316 } // namespace v8
OLDNEW
« no previous file with comments | « src/base/ieee754.h ('k') | src/bootstrapper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698