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 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 Loading... |
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 Loading... |
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 |
OLD | NEW |