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 // ==================================================== |
11 // | 11 // |
12 // The original source code covered by the above license above has been | 12 // The original source code covered by the above license above has been |
13 // modified significantly by Google Inc. | 13 // modified significantly by Google Inc. |
14 // Copyright 2016 the V8 project authors. All rights reserved. | 14 // Copyright 2016 the V8 project authors. All rights reserved. |
15 | 15 |
16 #include "src/base/ieee754.h" | 16 #include "src/base/ieee754.h" |
17 | 17 |
18 #include <cmath> | 18 #include <cmath> |
19 #include <limits> | 19 #include <limits> |
20 | 20 |
21 #include "src/base/build_config.h" | 21 #include "src/base/build_config.h" |
22 #include "src/base/macros.h" | 22 #include "src/base/macros.h" |
23 | 23 |
24 namespace v8 { | 24 namespace v8 { |
25 namespace base { | 25 namespace base { |
26 namespace ieee754 { | 26 namespace ieee754 { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 /* Fix-up typedefs so we can use the FreeBSD msun code mostly unmodified. */ | |
31 | |
32 #if V8_OS_WIN | |
33 | |
34 typedef uint32_t u_int32_t; | |
35 typedef uint64_t u_int64_t; | |
36 | |
37 #endif | |
38 | |
39 /* Disable "potential divide by 0" warning in Visual Studio compiler. */ | 30 /* Disable "potential divide by 0" warning in Visual Studio compiler. */ |
40 | 31 |
41 #if V8_CC_MSVC | 32 #if V8_CC_MSVC |
42 | 33 |
43 #pragma warning(disable : 4723) | 34 #pragma warning(disable : 4723) |
44 | 35 |
45 #endif | 36 #endif |
46 | 37 |
47 /* | 38 /* |
48 * The original fdlibm code used statements like: | 39 * The original fdlibm code used statements like: |
(...skipping 11 matching lines...) Expand all Loading... |
60 /* | 51 /* |
61 * A union which permits us to convert between a double and two 32 bit | 52 * A union which permits us to convert between a double and two 32 bit |
62 * ints. | 53 * ints. |
63 */ | 54 */ |
64 | 55 |
65 #if V8_TARGET_LITTLE_ENDIAN | 56 #if V8_TARGET_LITTLE_ENDIAN |
66 | 57 |
67 typedef union { | 58 typedef union { |
68 double value; | 59 double value; |
69 struct { | 60 struct { |
70 u_int32_t lsw; | 61 uint32_t lsw; |
71 u_int32_t msw; | 62 uint32_t msw; |
72 } parts; | 63 } parts; |
73 struct { | 64 struct { |
74 u_int64_t w; | 65 uint64_t w; |
75 } xparts; | 66 } xparts; |
76 } ieee_double_shape_type; | 67 } ieee_double_shape_type; |
77 | 68 |
78 #else | 69 #else |
79 | 70 |
80 typedef union { | 71 typedef union { |
81 double value; | 72 double value; |
82 struct { | 73 struct { |
83 u_int32_t msw; | 74 uint32_t msw; |
84 u_int32_t lsw; | 75 uint32_t lsw; |
85 } parts; | 76 } parts; |
86 struct { | 77 struct { |
87 u_int64_t w; | 78 uint64_t w; |
88 } xparts; | 79 } xparts; |
89 } ieee_double_shape_type; | 80 } ieee_double_shape_type; |
90 | 81 |
91 #endif | 82 #endif |
92 | 83 |
93 /* Get two 32 bit ints from a double. */ | 84 /* Get two 32 bit ints from a double. */ |
94 | 85 |
95 #define EXTRACT_WORDS(ix0, ix1, d) \ | 86 #define EXTRACT_WORDS(ix0, ix1, d) \ |
96 do { \ | 87 do { \ |
97 ieee_double_shape_type ew_u; \ | 88 ieee_double_shape_type ew_u; \ |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ | 214 pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ |
224 pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ | 215 pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ |
225 pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ | 216 pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ |
226 pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ | 217 pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ |
227 pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ | 218 pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ |
228 pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ | 219 pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ |
229 | 220 |
230 double z, w, t, r, fn; | 221 double z, w, t, r, fn; |
231 double tx[3]; | 222 double tx[3]; |
232 int32_t e0, i, j, nx, n, ix, hx; | 223 int32_t e0, i, j, nx, n, ix, hx; |
233 u_int32_t low; | 224 uint32_t low; |
234 | 225 |
235 z = 0; | 226 z = 0; |
236 GET_HIGH_WORD(hx, x); /* high word of x */ | 227 GET_HIGH_WORD(hx, x); /* high word of x */ |
237 ix = hx & 0x7fffffff; | 228 ix = hx & 0x7fffffff; |
238 if (ix <= 0x3fe921fb) { /* |x| ~<= pi/4 , no need for reduction */ | 229 if (ix <= 0x3fe921fb) { /* |x| ~<= pi/4 , no need for reduction */ |
239 y[0] = x; | 230 y[0] = x; |
240 y[1] = 0; | 231 y[1] = 0; |
241 return 0; | 232 return 0; |
242 } | 233 } |
243 if (ix < 0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ | 234 if (ix < 0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ |
(...skipping 23 matching lines...) Expand all Loading... |
267 } | 258 } |
268 if (ix <= 0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ | 259 if (ix <= 0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ |
269 t = fabs(x); | 260 t = fabs(x); |
270 n = static_cast<int32_t>(t * invpio2 + half); | 261 n = static_cast<int32_t>(t * invpio2 + half); |
271 fn = static_cast<double>(n); | 262 fn = static_cast<double>(n); |
272 r = t - fn * pio2_1; | 263 r = t - fn * pio2_1; |
273 w = fn * pio2_1t; /* 1st round good to 85 bit */ | 264 w = fn * pio2_1t; /* 1st round good to 85 bit */ |
274 if (n < 32 && ix != npio2_hw[n - 1]) { | 265 if (n < 32 && ix != npio2_hw[n - 1]) { |
275 y[0] = r - w; /* quick check no cancellation */ | 266 y[0] = r - w; /* quick check no cancellation */ |
276 } else { | 267 } else { |
277 u_int32_t high; | 268 uint32_t high; |
278 j = ix >> 20; | 269 j = ix >> 20; |
279 y[0] = r - w; | 270 y[0] = r - w; |
280 GET_HIGH_WORD(high, y[0]); | 271 GET_HIGH_WORD(high, y[0]); |
281 i = j - ((high >> 20) & 0x7ff); | 272 i = j - ((high >> 20) & 0x7ff); |
282 if (i > 16) { /* 2nd iteration needed, good to 118 */ | 273 if (i > 16) { /* 2nd iteration needed, good to 118 */ |
283 t = r; | 274 t = r; |
284 w = fn * pio2_2; | 275 w = fn * pio2_2; |
285 r = t - w; | 276 r = t - w; |
286 w = fn * pio2_2t - ((t - r) - w); | 277 w = fn * pio2_2t - ((t - r) - w); |
287 y[0] = r - w; | 278 y[0] = r - w; |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 #define pio4lo xxx[15] | 809 #define pio4lo xxx[15] |
819 #define T xxx | 810 #define T xxx |
820 | 811 |
821 double z, r, v, w, s; | 812 double z, r, v, w, s; |
822 int32_t ix, hx; | 813 int32_t ix, hx; |
823 | 814 |
824 GET_HIGH_WORD(hx, x); /* high word of x */ | 815 GET_HIGH_WORD(hx, x); /* high word of x */ |
825 ix = hx & 0x7fffffff; /* high word of |x| */ | 816 ix = hx & 0x7fffffff; /* high word of |x| */ |
826 if (ix < 0x3e300000) { /* x < 2**-28 */ | 817 if (ix < 0x3e300000) { /* x < 2**-28 */ |
827 if (static_cast<int>(x) == 0) { /* generate inexact */ | 818 if (static_cast<int>(x) == 0) { /* generate inexact */ |
828 u_int32_t low; | 819 uint32_t low; |
829 GET_LOW_WORD(low, x); | 820 GET_LOW_WORD(low, x); |
830 if (((ix | low) | (iy + 1)) == 0) { | 821 if (((ix | low) | (iy + 1)) == 0) { |
831 return one / fabs(x); | 822 return one / fabs(x); |
832 } else { | 823 } else { |
833 if (iy == 1) { | 824 if (iy == 1) { |
834 return x; | 825 return x; |
835 } else { /* compute -1 / (x+y) carefully */ | 826 } else { /* compute -1 / (x+y) carefully */ |
836 double a, t; | 827 double a, t; |
837 | 828 |
838 z = w = x + y; | 829 z = w = x + y; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 }; | 940 }; |
950 | 941 |
951 static const double one = 1.0, huge = 1.0e300; | 942 static const double one = 1.0, huge = 1.0e300; |
952 | 943 |
953 double w, s1, s2, z; | 944 double w, s1, s2, z; |
954 int32_t ix, hx, id; | 945 int32_t ix, hx, id; |
955 | 946 |
956 GET_HIGH_WORD(hx, x); | 947 GET_HIGH_WORD(hx, x); |
957 ix = hx & 0x7fffffff; | 948 ix = hx & 0x7fffffff; |
958 if (ix >= 0x44100000) { /* if |x| >= 2^66 */ | 949 if (ix >= 0x44100000) { /* if |x| >= 2^66 */ |
959 u_int32_t low; | 950 uint32_t low; |
960 GET_LOW_WORD(low, x); | 951 GET_LOW_WORD(low, x); |
961 if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (low != 0))) | 952 if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (low != 0))) |
962 return x + x; /* NaN */ | 953 return x + x; /* NaN */ |
963 if (hx > 0) | 954 if (hx > 0) |
964 return atanhi[3] + *(volatile double *)&atanlo[3]; | 955 return atanhi[3] + *(volatile double *)&atanlo[3]; |
965 else | 956 else |
966 return -atanhi[3] - *(volatile double *)&atanlo[3]; | 957 return -atanhi[3] - *(volatile double *)&atanlo[3]; |
967 } | 958 } |
968 if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ | 959 if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ |
969 if (ix < 0x3e400000) { /* |x| < 2^-27 */ | 960 if (ix < 0x3e400000) { /* |x| < 2^-27 */ |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1036 static const double | 1027 static const double |
1037 zero = 0.0, | 1028 zero = 0.0, |
1038 pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ | 1029 pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ |
1039 pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ | 1030 pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ |
1040 pi = 3.1415926535897931160E+00; /* 0x400921FB, 0x54442D18 */ | 1031 pi = 3.1415926535897931160E+00; /* 0x400921FB, 0x54442D18 */ |
1041 static volatile double pi_lo = | 1032 static volatile double pi_lo = |
1042 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ | 1033 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ |
1043 | 1034 |
1044 double z; | 1035 double z; |
1045 int32_t k, m, hx, hy, ix, iy; | 1036 int32_t k, m, hx, hy, ix, iy; |
1046 u_int32_t lx, ly; | 1037 uint32_t lx, ly; |
1047 | 1038 |
1048 EXTRACT_WORDS(hx, lx, x); | 1039 EXTRACT_WORDS(hx, lx, x); |
1049 ix = hx & 0x7fffffff; | 1040 ix = hx & 0x7fffffff; |
1050 EXTRACT_WORDS(hy, ly, y); | 1041 EXTRACT_WORDS(hy, ly, y); |
1051 iy = hy & 0x7fffffff; | 1042 iy = hy & 0x7fffffff; |
1052 if (((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x7ff00000) || | 1043 if (((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x7ff00000) || |
1053 ((iy | ((ly | -static_cast<int32_t>(ly)) >> 31)) > 0x7ff00000)) { | 1044 ((iy | ((ly | -static_cast<int32_t>(ly)) >> 31)) > 0x7ff00000)) { |
1054 return x + y; /* x or y is NaN */ | 1045 return x + y; /* x or y is NaN */ |
1055 } | 1046 } |
1056 if (((hx - 0x3ff00000) | lx) == 0) return atan(y); /* x=1.0 */ | 1047 if (((hx - 0x3ff00000) | lx) == 0) return atan(y); /* x=1.0 */ |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ | 1252 P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ |
1262 P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ | 1253 P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ |
1263 | 1254 |
1264 static volatile double | 1255 static volatile double |
1265 huge = 1.0e+300, | 1256 huge = 1.0e+300, |
1266 twom1000 = 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ | 1257 twom1000 = 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ |
1267 two1023 = 8.988465674311579539e307; /* 0x1p1023 */ | 1258 two1023 = 8.988465674311579539e307; /* 0x1p1023 */ |
1268 | 1259 |
1269 double y, hi = 0.0, lo = 0.0, c, t, twopk; | 1260 double y, hi = 0.0, lo = 0.0, c, t, twopk; |
1270 int32_t k = 0, xsb; | 1261 int32_t k = 0, xsb; |
1271 u_int32_t hx; | 1262 uint32_t hx; |
1272 | 1263 |
1273 GET_HIGH_WORD(hx, x); | 1264 GET_HIGH_WORD(hx, x); |
1274 xsb = (hx >> 31) & 1; /* sign bit of x */ | 1265 xsb = (hx >> 31) & 1; /* sign bit of x */ |
1275 hx &= 0x7fffffff; /* high word of |x| */ | 1266 hx &= 0x7fffffff; /* high word of |x| */ |
1276 | 1267 |
1277 /* filter out non-finite argument */ | 1268 /* filter out non-finite argument */ |
1278 if (hx >= 0x40862E42) { /* if |x|>=709.78... */ | 1269 if (hx >= 0x40862E42) { /* if |x|>=709.78... */ |
1279 if (hx >= 0x7ff00000) { | 1270 if (hx >= 0x7ff00000) { |
1280 u_int32_t lx; | 1271 uint32_t lx; |
1281 GET_LOW_WORD(lx, x); | 1272 GET_LOW_WORD(lx, x); |
1282 if (((hx & 0xfffff) | lx) != 0) | 1273 if (((hx & 0xfffff) | lx) != 0) |
1283 return x + x; /* NaN */ | 1274 return x + x; /* NaN */ |
1284 else | 1275 else |
1285 return (xsb == 0) ? x : 0.0; /* exp(+-inf)={inf,0} */ | 1276 return (xsb == 0) ? x : 0.0; /* exp(+-inf)={inf,0} */ |
1286 } | 1277 } |
1287 if (x > o_threshold) return huge * huge; /* overflow */ | 1278 if (x > o_threshold) return huge * huge; /* overflow */ |
1288 if (x < u_threshold) return twom1000 * twom1000; /* underflow */ | 1279 if (x < u_threshold) return twom1000 * twom1000; /* underflow */ |
1289 } | 1280 } |
1290 | 1281 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 * atanh(NaN) is that NaN with no signal; | 1335 * atanh(NaN) is that NaN with no signal; |
1345 * atanh(+-1) is +-INF with signal. | 1336 * atanh(+-1) is +-INF with signal. |
1346 * | 1337 * |
1347 */ | 1338 */ |
1348 double atanh(double x) { | 1339 double atanh(double x) { |
1349 static const double one = 1.0, huge = 1e300; | 1340 static const double one = 1.0, huge = 1e300; |
1350 static const double zero = 0.0; | 1341 static const double zero = 0.0; |
1351 | 1342 |
1352 double t; | 1343 double t; |
1353 int32_t hx, ix; | 1344 int32_t hx, ix; |
1354 u_int32_t lx; | 1345 uint32_t lx; |
1355 EXTRACT_WORDS(hx, lx, x); | 1346 EXTRACT_WORDS(hx, lx, x); |
1356 ix = hx & 0x7fffffff; | 1347 ix = hx & 0x7fffffff; |
1357 if ((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x3ff00000) /* |x|>1 */ | 1348 if ((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x3ff00000) /* |x|>1 */ |
1358 return (x - x) / (x - x); | 1349 return (x - x) / (x - x); |
1359 if (ix == 0x3ff00000) return x / zero; | 1350 if (ix == 0x3ff00000) return x / zero; |
1360 if (ix < 0x3e300000 && (huge + x) > zero) return x; /* x<2**-28 */ | 1351 if (ix < 0x3e300000 && (huge + x) > zero) return x; /* x<2**-28 */ |
1361 SET_HIGH_WORD(x, ix); | 1352 SET_HIGH_WORD(x, ix); |
1362 if (ix < 0x3fe00000) { /* x < 0.5 */ | 1353 if (ix < 0x3fe00000) { /* x < 0.5 */ |
1363 t = x + x; | 1354 t = x + x; |
1364 t = 0.5 * log1p(t + t * x / (one - x)); | 1355 t = 0.5 * log1p(t + t * x / (one - x)); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1432 Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ | 1423 Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ |
1433 Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ | 1424 Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ |
1434 Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ | 1425 Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ |
1435 Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ | 1426 Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ |
1436 | 1427 |
1437 static const double zero = 0.0; | 1428 static const double zero = 0.0; |
1438 static volatile double vzero = 0.0; | 1429 static volatile double vzero = 0.0; |
1439 | 1430 |
1440 double hfsq, f, s, z, R, w, t1, t2, dk; | 1431 double hfsq, f, s, z, R, w, t1, t2, dk; |
1441 int32_t k, hx, i, j; | 1432 int32_t k, hx, i, j; |
1442 u_int32_t lx; | 1433 uint32_t lx; |
1443 | 1434 |
1444 EXTRACT_WORDS(hx, lx, x); | 1435 EXTRACT_WORDS(hx, lx, x); |
1445 | 1436 |
1446 k = 0; | 1437 k = 0; |
1447 if (hx < 0x00100000) { /* x < 2**-1022 */ | 1438 if (hx < 0x00100000) { /* x < 2**-1022 */ |
1448 if (((hx & 0x7fffffff) | lx) == 0) | 1439 if (((hx & 0x7fffffff) | lx) == 0) |
1449 return -two54 / vzero; /* log(+-0)=-inf */ | 1440 return -two54 / vzero; /* log(+-0)=-inf */ |
1450 if (hx < 0) return (x - x) / zero; /* log(-#) = NaN */ | 1441 if (hx < 0) return (x - x) / zero; /* log(-#) = NaN */ |
1451 k -= 54; | 1442 k -= 54; |
1452 x *= two54; /* subnormal number, scale up x */ | 1443 x *= two54; /* subnormal number, scale up x */ |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1759 static const double | 1750 static const double |
1760 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ | 1751 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ |
1761 ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ | 1752 ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ |
1762 ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */ | 1753 ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */ |
1763 | 1754 |
1764 static const double zero = 0.0; | 1755 static const double zero = 0.0; |
1765 static volatile double vzero = 0.0; | 1756 static volatile double vzero = 0.0; |
1766 | 1757 |
1767 double f, hfsq, hi, lo, r, val_hi, val_lo, w, y; | 1758 double f, hfsq, hi, lo, r, val_hi, val_lo, w, y; |
1768 int32_t i, k, hx; | 1759 int32_t i, k, hx; |
1769 u_int32_t lx; | 1760 uint32_t lx; |
1770 | 1761 |
1771 EXTRACT_WORDS(hx, lx, x); | 1762 EXTRACT_WORDS(hx, lx, x); |
1772 | 1763 |
1773 k = 0; | 1764 k = 0; |
1774 if (hx < 0x00100000) { /* x < 2**-1022 */ | 1765 if (hx < 0x00100000) { /* x < 2**-1022 */ |
1775 if (((hx & 0x7fffffff) | lx) == 0) | 1766 if (((hx & 0x7fffffff) | lx) == 0) |
1776 return -two54 / vzero; /* log(+-0)=-inf */ | 1767 return -two54 / vzero; /* log(+-0)=-inf */ |
1777 if (hx < 0) return (x - x) / zero; /* log(-#) = NaN */ | 1768 if (hx < 0) return (x - x) / zero; /* log(-#) = NaN */ |
1778 k -= 54; | 1769 k -= 54; |
1779 x *= two54; /* subnormal number, scale up x */ | 1770 x *= two54; /* subnormal number, scale up x */ |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ | 1857 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ |
1867 ivln10 = 4.34294481903251816668e-01, | 1858 ivln10 = 4.34294481903251816668e-01, |
1868 log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ | 1859 log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ |
1869 log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ | 1860 log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ |
1870 | 1861 |
1871 static const double zero = 0.0; | 1862 static const double zero = 0.0; |
1872 static volatile double vzero = 0.0; | 1863 static volatile double vzero = 0.0; |
1873 | 1864 |
1874 double y; | 1865 double y; |
1875 int32_t i, k, hx; | 1866 int32_t i, k, hx; |
1876 u_int32_t lx; | 1867 uint32_t lx; |
1877 | 1868 |
1878 EXTRACT_WORDS(hx, lx, x); | 1869 EXTRACT_WORDS(hx, lx, x); |
1879 | 1870 |
1880 k = 0; | 1871 k = 0; |
1881 if (hx < 0x00100000) { /* x < 2**-1022 */ | 1872 if (hx < 0x00100000) { /* x < 2**-1022 */ |
1882 if (((hx & 0x7fffffff) | lx) == 0) | 1873 if (((hx & 0x7fffffff) | lx) == 0) |
1883 return -two54 / vzero; /* log(+-0)=-inf */ | 1874 return -two54 / vzero; /* log(+-0)=-inf */ |
1884 if (hx < 0) return (x - x) / zero; /* log(-#) = NaN */ | 1875 if (hx < 0) return (x - x) / zero; /* log(-#) = NaN */ |
1885 k -= 54; | 1876 k -= 54; |
1886 x *= two54; /* subnormal number, scale up x */ | 1877 x *= two54; /* subnormal number, scale up x */ |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2008 Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ | 1999 Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ |
2009 Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ | 2000 Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ |
2010 Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ | 2001 Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ |
2011 Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ | 2002 Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ |
2012 Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ | 2003 Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ |
2013 | 2004 |
2014 static volatile double huge = 1.0e+300; | 2005 static volatile double huge = 1.0e+300; |
2015 | 2006 |
2016 double y, hi, lo, c, t, e, hxs, hfx, r1, twopk; | 2007 double y, hi, lo, c, t, e, hxs, hfx, r1, twopk; |
2017 int32_t k, xsb; | 2008 int32_t k, xsb; |
2018 u_int32_t hx; | 2009 uint32_t hx; |
2019 | 2010 |
2020 GET_HIGH_WORD(hx, x); | 2011 GET_HIGH_WORD(hx, x); |
2021 xsb = hx & 0x80000000; /* sign bit of x */ | 2012 xsb = hx & 0x80000000; /* sign bit of x */ |
2022 hx &= 0x7fffffff; /* high word of |x| */ | 2013 hx &= 0x7fffffff; /* high word of |x| */ |
2023 | 2014 |
2024 /* filter out huge and non-finite argument */ | 2015 /* filter out huge and non-finite argument */ |
2025 if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */ | 2016 if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */ |
2026 if (hx >= 0x40862E42) { /* if |x|>=709.78... */ | 2017 if (hx >= 0x40862E42) { /* if |x|>=709.78... */ |
2027 if (hx >= 0x7ff00000) { | 2018 if (hx >= 0x7ff00000) { |
2028 u_int32_t low; | 2019 uint32_t low; |
2029 GET_LOW_WORD(low, x); | 2020 GET_LOW_WORD(low, x); |
2030 if (((hx & 0xfffff) | low) != 0) | 2021 if (((hx & 0xfffff) | low) != 0) |
2031 return x + x; /* NaN */ | 2022 return x + x; /* NaN */ |
2032 else | 2023 else |
2033 return (xsb == 0) ? x : -1.0; /* exp(+-inf)={inf,-1} */ | 2024 return (xsb == 0) ? x : -1.0; /* exp(+-inf)={inf,-1} */ |
2034 } | 2025 } |
2035 if (x > o_threshold) return huge * huge; /* overflow */ | 2026 if (x > o_threshold) return huge * huge; /* overflow */ |
2036 } | 2027 } |
2037 if (xsb != 0) { /* x < -56*ln2, return -1.0 with inexact */ | 2028 if (xsb != 0) { /* x < -56*ln2, return -1.0 with inexact */ |
2038 if (x + tiny < 0.0) /* raise inexact */ | 2029 if (x + tiny < 0.0) /* raise inexact */ |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 SET_HIGH_WORD(t, ((0x3ff - k) << 20)); /* 2^-k */ | 2097 SET_HIGH_WORD(t, ((0x3ff - k) << 20)); /* 2^-k */ |
2107 y = x - (e + t); | 2098 y = x - (e + t); |
2108 y += one; | 2099 y += one; |
2109 y = y * twopk; | 2100 y = y * twopk; |
2110 } | 2101 } |
2111 } | 2102 } |
2112 return y; | 2103 return y; |
2113 } | 2104 } |
2114 | 2105 |
2115 double cbrt(double x) { | 2106 double cbrt(double x) { |
2116 static const u_int32_t | 2107 static const uint32_t |
2117 B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */ | 2108 B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */ |
2118 B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */ | 2109 B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */ |
2119 | 2110 |
2120 /* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */ | 2111 /* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */ |
2121 static const double P0 = 1.87595182427177009643, /* 0x3ffe03e6, 0x0f61e692 */ | 2112 static const double P0 = 1.87595182427177009643, /* 0x3ffe03e6, 0x0f61e692 */ |
2122 P1 = -1.88497979543377169875, /* 0xbffe28e0, 0x92f02420 */ | 2113 P1 = -1.88497979543377169875, /* 0xbffe28e0, 0x92f02420 */ |
2123 P2 = 1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */ | 2114 P2 = 1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */ |
2124 P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */ | 2115 P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */ |
2125 P4 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */ | 2116 P4 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */ |
2126 | 2117 |
2127 int32_t hx; | 2118 int32_t hx; |
2128 union { | 2119 union { |
2129 double value; | 2120 double value; |
2130 uint64_t bits; | 2121 uint64_t bits; |
2131 } u; | 2122 } u; |
2132 double r, s, t = 0.0, w; | 2123 double r, s, t = 0.0, w; |
2133 u_int32_t sign; | 2124 uint32_t sign; |
2134 u_int32_t high, low; | 2125 uint32_t high, low; |
2135 | 2126 |
2136 EXTRACT_WORDS(hx, low, x); | 2127 EXTRACT_WORDS(hx, low, x); |
2137 sign = hx & 0x80000000; /* sign= sign(x) */ | 2128 sign = hx & 0x80000000; /* sign= sign(x) */ |
2138 hx ^= sign; | 2129 hx ^= sign; |
2139 if (hx >= 0x7ff00000) return (x + x); /* cbrt(NaN,INF) is itself */ | 2130 if (hx >= 0x7ff00000) return (x + x); /* cbrt(NaN,INF) is itself */ |
2140 | 2131 |
2141 /* | 2132 /* |
2142 * Rough cbrt to 5 bits: | 2133 * Rough cbrt to 5 bits: |
2143 * cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3) | 2134 * cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3) |
2144 * where e is integral and >= 0, m is real and in [0, 1), and "/" and | 2135 * where e is integral and >= 0, m is real and in [0, 1), and "/" and |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2307 /* argument reduction needed */ | 2298 /* argument reduction needed */ |
2308 n = __ieee754_rem_pio2(x, y); | 2299 n = __ieee754_rem_pio2(x, y); |
2309 /* 1 -> n even, -1 -> n odd */ | 2300 /* 1 -> n even, -1 -> n odd */ |
2310 return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1)); | 2301 return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1)); |
2311 } | 2302 } |
2312 } | 2303 } |
2313 | 2304 |
2314 } // namespace ieee754 | 2305 } // namespace ieee754 |
2315 } // namespace base | 2306 } // namespace base |
2316 } // namespace v8 | 2307 } // namespace v8 |
OLD | NEW |