16 #include "src/base/ieee754.h" 21 #include "src/base/build_config.h" 22 #include "src/base/macros.h" 34 #pragma warning(disable : 4723) 57 #if V8_TARGET_LITTLE_ENDIAN 68 } ieee_double_shape_type;
81 } ieee_double_shape_type;
87 #define EXTRACT_WORDS(ix0, ix1, d) \ 89 ieee_double_shape_type ew_u; \ 91 (ix0) = ew_u.parts.msw; \ 92 (ix1) = ew_u.parts.lsw; \ 96 #define EXTRACT_WORD64(ix, d) \ 98 ieee_double_shape_type ew_u; \ 100 (ix) = ew_u.xparts.w; \ 105 #define GET_HIGH_WORD(i, d) \ 107 ieee_double_shape_type gh_u; \ 109 (i) = gh_u.parts.msw; \ 114 #define GET_LOW_WORD(i, d) \ 116 ieee_double_shape_type gl_u; \ 118 (i) = gl_u.parts.lsw; \ 123 #define INSERT_WORDS(d, ix0, ix1) \ 125 ieee_double_shape_type iw_u; \ 126 iw_u.parts.msw = (ix0); \ 127 iw_u.parts.lsw = (ix1); \ 132 #define INSERT_WORD64(d, ix) \ 134 ieee_double_shape_type iw_u; \ 135 iw_u.xparts.w = (ix); \ 141 #define SET_HIGH_WORD(d, v) \ 143 ieee_double_shape_type sh_u; \ 145 sh_u.parts.msw = (v); \ 151 #define SET_LOW_WORD(d, v) \ 153 ieee_double_shape_type sl_u; \ 155 sl_u.parts.lsw = (v); \ 161 #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) 163 int32_t __ieee754_rem_pio2(
double x,
double* y) V8_WARN_UNUSED_RESULT;
164 double __kernel_cos(
double x,
double y) V8_WARN_UNUSED_RESULT;
165 int __kernel_rem_pio2(
double* x,
double* y,
int e0,
int nx,
int prec,
166 const int32_t* ipio2) V8_WARN_UNUSED_RESULT;
167 double __kernel_sin(
double x,
double y,
int iy) V8_WARN_UNUSED_RESULT;
174 int32_t __ieee754_rem_pio2(
double x,
double *y) {
178 static const int32_t two_over_pi[] = {
179 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C,
180 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 0x424DD2, 0xE00649,
181 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44,
182 0x84E99C, 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B,
183 0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D,
184 0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
185 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330,
186 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, 0xE61B08,
187 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA,
188 0x73A8C9, 0x60E27B, 0xC08C6B,
191 static const int32_t npio2_hw[] = {
192 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
193 0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
194 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
195 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
196 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
197 0x404858EB, 0x404921FB,
211 zero = 0.00000000000000000000e+00,
212 half = 5.00000000000000000000e-01,
213 two24 = 1.67772160000000000000e+07,
214 invpio2 = 6.36619772367581382433e-01,
215 pio2_1 = 1.57079632673412561417e+00,
216 pio2_1t = 6.07710050650619224932e-11,
217 pio2_2 = 6.07710050630396597660e-11,
218 pio2_2t = 2.02226624879595063154e-21,
219 pio2_3 = 2.02226624871116645580e-21,
220 pio2_3t = 8.47842766036889956997e-32;
222 double z, w, t, r, fn;
224 int32_t e0,
i, j, nx, n, ix, hx;
228 GET_HIGH_WORD(hx, x);
229 ix = hx & 0x7FFFFFFF;
230 if (ix <= 0x3FE921FB) {
235 if (ix < 0x4002D97C) {
238 if (ix != 0x3FF921FB) {
240 y[1] = (z - y[0]) - pio2_1t;
244 y[1] = (z - y[0]) - pio2_2t;
249 if (ix != 0x3FF921FB) {
251 y[1] = (z - y[0]) + pio2_1t;
255 y[1] = (z - y[0]) + pio2_2t;
260 if (ix <= 0x413921FB) {
262 n =
static_cast<int32_t
>(t * invpio2 + half);
263 fn =
static_cast<double>(n);
266 if (n < 32 && ix != npio2_hw[n - 1]) {
272 GET_HIGH_WORD(high, y[0]);
273 i = j - ((high >> 20) & 0x7FF);
278 w = fn * pio2_2t - ((t - r) - w);
280 GET_HIGH_WORD(high, y[0]);
281 i = j - ((high >> 20) & 0x7FF);
286 w = fn * pio2_3t - ((t - r) - w);
291 y[1] = (r - y[0]) - w;
303 if (ix >= 0x7FF00000) {
308 GET_LOW_WORD(low, x);
309 SET_LOW_WORD(z, low);
310 e0 = (ix >> 20) - 1046;
311 SET_HIGH_WORD(z, ix - static_cast<int32_t>(e0 << 20));
312 for (
i = 0;
i < 2;
i++) {
313 tx[
i] =
static_cast<double>(
static_cast<int32_t
>(z));
314 z = (z - tx[
i]) * two24;
318 while (tx[nx - 1] == zero) nx--;
319 n = __kernel_rem_pio2(tx, y, e0, nx, 2, two_over_pi);
361 V8_INLINE
double __kernel_cos(
double x,
double y) {
363 one = 1.00000000000000000000e+00,
364 C1 = 4.16666666666666019037e-02,
365 C2 = -1.38888888888741095749e-03,
366 C3 = 2.48015872894767294178e-05,
367 C4 = -2.75573143513906633035e-07,
368 C5 = 2.08757232129817482790e-09,
369 C6 = -1.13596475577881948265e-11;
371 double a, iz, z, r, qx;
373 GET_HIGH_WORD(ix, x);
375 if (ix < 0x3E400000) {
376 if (static_cast<int>(x) == 0)
return one;
379 r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6)))));
380 if (ix < 0x3FD33333) {
381 return one - (0.5 * z - (z * r - x * y));
383 if (ix > 0x3FE90000) {
386 INSERT_WORDS(qx, ix - 0x00200000, 0);
390 return a - (iz - (z * r - x * y));
499 int __kernel_rem_pio2(
double *x,
double *y,
int e0,
int nx,
int prec,
500 const int32_t *ipio2) {
507 static const int init_jk[] = {2, 3, 4, 6};
509 static const double PIo2[] = {
510 1.57079625129699707031e+00,
511 7.54978941586159635335e-08,
512 5.39030252995776476554e-15,
513 3.28200341580791294123e-22,
514 1.27065575308067607349e-29,
515 1.22933308981111328932e-36,
516 2.73370053816464559624e-44,
517 2.16741683877804819444e-51,
523 two24 = 1.67772160000000000000e+07,
524 twon24 = 5.96046447753906250000e-08;
526 int32_t jz, jx, jv, jp, jk, carry, n, iq[20],
i, j, k, m, q0, ih;
527 double z, fw, f[20], fq[20], q[20];
537 q0 = e0 - 24 * (jv + 1);
542 for (
i = 0;
i <= m;
i++, j++) {
543 f[
i] = (j < 0) ? zero : static_cast<double>(ipio2[j]);
547 for (
i = 0;
i <= jk;
i++) {
548 for (j = 0, fw = 0.0; j <= jx; j++) fw += x[j] * f[jx +
i - j];
555 for (
i = 0, j = jz, z = q[jz]; j > 0;
i++, j--) {
556 fw =
static_cast<double>(
static_cast<int32_t
>(twon24 * z));
557 iq[
i] =
static_cast<int32_t
>(z - two24 * fw);
563 z -= 8.0 * floor(z * 0.125);
564 n =
static_cast<int32_t
>(z);
565 z -=
static_cast<double>(n);
568 i = (iq[jz - 1] >> (24 - q0));
570 iq[jz - 1] -=
i << (24 - q0);
571 ih = iq[jz - 1] >> (23 - q0);
572 }
else if (q0 == 0) {
573 ih = iq[jz - 1] >> 23;
574 }
else if (z >= 0.5) {
581 for (
i = 0;
i < jz;
i++) {
586 iq[
i] = 0x1000000 - j;
589 iq[
i] = 0xFFFFFF - j;
595 iq[jz - 1] &= 0x7FFFFF;
598 iq[jz - 1] &= 0x3FFFFF;
604 if (carry != 0) z -= scalbn(one, q0);
611 for (
i = jz - 1;
i >= jk;
i--) j |= iq[
i];
613 for (k = 1; jk >= k && iq[jk - k] == 0; k++) {
617 for (
i = jz + 1;
i <= jz + k;
i++) {
618 f[jx +
i] = ipio2[jv +
i];
619 for (j = 0, fw = 0.0; j <= jx; j++) fw += x[j] * f[jx +
i - j];
631 while (iq[jz] == 0) {
638 fw =
static_cast<double>(
static_cast<int32_t
>(twon24 * z));
639 iq[jz] = z - two24 * fw;
649 fw = scalbn(one, q0);
650 for (
i = jz;
i >= 0;
i--) {
656 for (
i = jz;
i >= 0;
i--) {
657 for (fw = 0.0, k = 0; k <= jp && k <= jz -
i; k++) fw += PIo2[k] * q[
i + k];
665 for (
i = jz;
i >= 0;
i--) fw += fq[
i];
666 y[0] = (ih == 0) ? fw : -fw;
671 for (
i = jz;
i >= 0;
i--) fw += fq[
i];
672 y[0] = (ih == 0) ? fw : -fw;
674 for (
i = 1;
i <= jz;
i++) fw += fq[
i];
675 y[1] = (ih == 0) ? fw : -fw;
678 for (
i = jz;
i > 0;
i--) {
679 fw = fq[
i - 1] + fq[
i];
680 fq[
i] += fq[
i - 1] - fw;
683 for (
i = jz;
i > 1;
i--) {
684 fw = fq[
i - 1] + fq[
i];
685 fq[
i] += fq[
i - 1] - fw;
688 for (fw = 0.0,
i = jz;
i >= 2;
i--) fw += fq[
i];
729 V8_INLINE
double __kernel_sin(
double x,
double y,
int iy) {
731 half = 5.00000000000000000000e-01,
732 S1 = -1.66666666666666324348e-01,
733 S2 = 8.33333333332248946124e-03,
734 S3 = -1.98412698298579493134e-04,
735 S4 = 2.75573137070700676789e-06,
736 S5 = -2.50507602534068634195e-08,
737 S6 = 1.58969099521155010221e-10;
741 GET_HIGH_WORD(ix, x);
743 if (ix < 0x3E400000) {
744 if (static_cast<int>(x) == 0)
return x;
748 r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6)));
750 return x + v * (S1 + z * r);
752 return x - ((z * (half * y - v * r) - y) - v * S1);
789 double __kernel_tan(
double x,
double y,
int iy) {
790 static const double xxx[] = {
791 3.33333333333334091986e-01,
792 1.33333333333201242699e-01,
793 5.39682539762260521377e-02,
794 2.18694882948595424599e-02,
795 8.86323982359930005737e-03,
796 3.59207910759131235356e-03,
797 1.45620945432529025516e-03,
798 5.88041240820264096874e-04,
799 2.46463134818469906812e-04,
800 7.81794442939557092300e-05,
801 7.14072491382608190305e-05,
802 -1.85586374855275456654e-05,
803 2.59073051863633712884e-05,
804 1.00000000000000000000e+00,
805 7.85398163397448278999e-01,
806 3.06161699786838301793e-17
810 #define pio4lo xxx[15] 813 double z, r, v, w, s;
816 GET_HIGH_WORD(hx, x);
817 ix = hx & 0x7FFFFFFF;
818 if (ix < 0x3E300000) {
819 if (static_cast<int>(x) == 0) {
821 GET_LOW_WORD(low, x);
822 if (((ix | low) | (iy + 1)) == 0) {
823 return one / fabs(x);
836 return t + a * (s + t * v);
841 if (ix >= 0x3FE59428) {
858 r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + w * T[11]))));
860 (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + w * T[12])))));
862 r = y + z * (s * (r + v) + y);
865 if (ix >= 0x3FE59428) {
867 return (1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - (w * w / (w + v) - r)));
884 return t + a * (s + t * v);
918 double acos(
double x) {
920 one = 1.00000000000000000000e+00,
921 pi = 3.14159265358979311600e+00,
922 pio2_hi = 1.57079632679489655800e+00,
923 pio2_lo = 6.12323399573676603587e-17,
924 pS0 = 1.66666666666666657415e-01,
925 pS1 = -3.25565818622400915405e-01,
926 pS2 = 2.01212532134862925881e-01,
927 pS3 = -4.00555345006794114027e-02,
928 pS4 = 7.91534994289814532176e-04,
929 pS5 = 3.47933107596021167570e-05,
930 qS1 = -2.40339491173441421878e+00,
931 qS2 = 2.02094576023350569471e+00,
932 qS3 = -6.88283971605453293030e-01,
933 qS4 = 7.70381505559019352791e-02;
935 double z, p, q, r, w, s, c, df;
937 GET_HIGH_WORD(hx, x);
938 ix = hx & 0x7FFFFFFF;
939 if (ix >= 0x3FF00000) {
942 if (((ix - 0x3FF00000) | lx) == 0) {
946 return pi + 2.0 * pio2_lo;
948 return (x - x) / (x - x);
950 if (ix < 0x3FE00000) {
951 if (ix <= 0x3C600000)
return pio2_hi + pio2_lo;
953 p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
954 q = one + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
956 return pio2_hi - (x - (pio2_lo - x * r));
959 p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
960 q = one + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
964 return pi - 2.0 * (s + w);
970 c = (z - df * df) / (s + df);
971 p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
972 q = one + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
975 return 2.0 * (df + w);
992 double acosh(
double x) {
995 ln2 = 6.93147180559945286227e-01;
999 EXTRACT_WORDS(hx, lx, x);
1000 if (hx < 0x3FF00000) {
1001 return (x - x) / (x - x);
1002 }
else if (hx >= 0x41B00000) {
1003 if (hx >= 0x7FF00000) {
1006 return log(x) + ln2;
1008 }
else if (((hx - 0x3FF00000) | lx) == 0) {
1010 }
else if (hx > 0x40000000) {
1012 return log(2.0 * x - one / (x + sqrt(t - one)));
1015 return log1p(t + sqrt(2.0 * t + t * t));
1047 double asin(
double x) {
1049 one = 1.00000000000000000000e+00,
1051 pio2_hi = 1.57079632679489655800e+00,
1052 pio2_lo = 6.12323399573676603587e-17,
1053 pio4_hi = 7.85398163397448278999e-01,
1055 pS0 = 1.66666666666666657415e-01,
1056 pS1 = -3.25565818622400915405e-01,
1057 pS2 = 2.01212532134862925881e-01,
1058 pS3 = -4.00555345006794114027e-02,
1059 pS4 = 7.91534994289814532176e-04,
1060 pS5 = 3.47933107596021167570e-05,
1061 qS1 = -2.40339491173441421878e+00,
1062 qS2 = 2.02094576023350569471e+00,
1063 qS3 = -6.88283971605453293030e-01,
1064 qS4 = 7.70381505559019352791e-02;
1066 double t, w, p, q, c, r, s;
1070 GET_HIGH_WORD(hx, x);
1071 ix = hx & 0x7FFFFFFF;
1072 if (ix >= 0x3FF00000) {
1074 GET_LOW_WORD(lx, x);
1075 if (((ix - 0x3FF00000) | lx) == 0)
1076 return x * pio2_hi + x * pio2_lo;
1077 return (x - x) / (x - x);
1078 }
else if (ix < 0x3FE00000) {
1079 if (ix < 0x3E400000) {
1080 if (huge + x > one)
return x;
1084 p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5)))));
1085 q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4)));
1092 p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5)))));
1093 q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4)));
1095 if (ix >= 0x3FEF3333) {
1097 t = pio2_hi - (2.0 * (s + s * w) - pio2_lo);
1101 c = (t - w * w) / (s + w);
1103 p = 2.0 * s * r - (pio2_lo - 2.0 * c);
1104 q = pio4_hi - 2.0 * w;
1105 t = pio4_hi - (p - q);
1122 double asinh(
double x) {
1124 one = 1.00000000000000000000e+00,
1125 ln2 = 6.93147180559945286227e-01,
1126 huge = 1.00000000000000000000e+300;
1130 GET_HIGH_WORD(hx, x);
1131 ix = hx & 0x7FFFFFFF;
1132 if (ix >= 0x7FF00000)
return x + x;
1133 if (ix < 0x3E300000) {
1134 if (huge + x > one)
return x;
1136 if (ix > 0x41B00000) {
1137 w = log(fabs(x)) + ln2;
1138 }
else if (ix > 0x40000000) {
1140 w = log(2.0 * t + one / (sqrt(x * x + one) + t));
1143 w = log1p(fabs(x) + t / (one + sqrt(one + t)));
1171 double atan(
double x) {
1172 static const double atanhi[] = {
1173 4.63647609000806093515e-01,
1174 7.85398163397448278999e-01,
1175 9.82793723247329054082e-01,
1176 1.57079632679489655800e+00,
1179 static const double atanlo[] = {
1180 2.26987774529616870924e-17,
1181 3.06161699786838301793e-17,
1182 1.39033110312309984516e-17,
1183 6.12323399573676603587e-17,
1186 static const double aT[] = {
1187 3.33333333333329318027e-01,
1188 -1.99999999998764832476e-01,
1189 1.42857142725034663711e-01,
1190 -1.11111104054623557880e-01,
1191 9.09088713343650656196e-02,
1192 -7.69187620504482999495e-02,
1193 6.66107313738753120669e-02,
1194 -5.83357013379057348645e-02,
1195 4.97687799461593236017e-02,
1196 -3.65315727442169155270e-02,
1197 1.62858201153657823623e-02,
1200 static const double one = 1.0, huge = 1.0e300;
1202 double w, s1, s2, z;
1205 GET_HIGH_WORD(hx, x);
1206 ix = hx & 0x7FFFFFFF;
1207 if (ix >= 0x44100000) {
1209 GET_LOW_WORD(low, x);
1210 if (ix > 0x7FF00000 || (ix == 0x7FF00000 && (low != 0)))
1213 return atanhi[3] + *
const_cast<volatile double*
>(&atanlo[3]);
1215 return -atanhi[3] - *
const_cast<volatile double*
>(&atanlo[3]);
1217 if (ix < 0x3FDC0000) {
1218 if (ix < 0x3E400000) {
1219 if (huge + x > one)
return x;
1224 if (ix < 0x3FF30000) {
1225 if (ix < 0x3FE60000) {
1227 x = (2.0 * x - one) / (2.0 + x);
1230 x = (x - one) / (x + one);
1233 if (ix < 0x40038000) {
1235 x = (x - 1.5) / (one + 1.5 * x);
1247 w * (aT[2] + w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10])))));
1248 s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9]))));
1250 return x - x * (s1 + s2);
1252 z = atanhi[id] - ((x * (s1 + s2) - atanlo[
id]) - x);
1253 return (hx < 0) ? -z : z;
1283 double atan2(
double y,
double x) {
1284 static volatile double tiny = 1.0e-300;
1287 pi_o_4 = 7.8539816339744827900E-01,
1288 pi_o_2 = 1.5707963267948965580E+00,
1289 pi = 3.1415926535897931160E+00;
1290 static volatile double pi_lo =
1291 1.2246467991473531772E-16;
1294 int32_t k, m, hx, hy, ix, iy;
1297 EXTRACT_WORDS(hx, lx, x);
1298 ix = hx & 0x7FFFFFFF;
1299 EXTRACT_WORDS(hy, ly, y);
1300 iy = hy & 0x7FFFFFFF;
1301 if (((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x7FF00000) ||
1302 ((iy | ((ly | -static_cast<int32_t>(ly)) >> 31)) > 0x7FF00000)) {
1305 if (((hx - 0x3FF00000) | lx) == 0)
return atan(y);
1306 m = ((hy >> 31) & 1) | ((hx >> 30) & 2);
1309 if ((iy | ly) == 0) {
1321 if ((ix | lx) == 0)
return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
1324 if (ix == 0x7FF00000) {
1325 if (iy == 0x7FF00000) {
1328 return pi_o_4 + tiny;
1330 return -pi_o_4 - tiny;
1332 return 3.0 * pi_o_4 + tiny;
1334 return -3.0 * pi_o_4 - tiny;
1350 if (iy == 0x7FF00000)
return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
1353 k = (iy - ix) >> 20;
1355 z = pi_o_2 + 0.5 * pi_lo;
1357 }
else if (hx < 0 && k < -60) {
1360 z = atan(fabs(y / x));
1368 return pi - (z - pi_lo);
1370 return (z - pi_lo) - pi;
1404 double cos(
double x) {
1405 double y[2], z = 0.0;
1409 GET_HIGH_WORD(ix, x);
1413 if (ix <= 0x3FE921FB) {
1414 return __kernel_cos(x, z);
1415 }
else if (ix >= 0x7FF00000) {
1420 n = __ieee754_rem_pio2(x, y);
1423 return __kernel_cos(y[0], y[1]);
1425 return -__kernel_sin(y[0], y[1], 1);
1427 return -__kernel_cos(y[0], y[1]);
1429 return __kernel_sin(y[0], y[1], 1);
1496 double exp(
double x) {
1499 halF[2] = {0.5, -0.5},
1500 o_threshold = 7.09782712893383973096e+02,
1501 u_threshold = -7.45133219101941108420e+02,
1502 ln2HI[2] = {6.93147180369123816490e-01,
1503 -6.93147180369123816490e-01},
1504 ln2LO[2] = {1.90821492927058770002e-10,
1505 -1.90821492927058770002e-10},
1506 invln2 = 1.44269504088896338700e+00,
1507 P1 = 1.66666666666666019037e-01,
1508 P2 = -2.77777777770155933842e-03,
1509 P3 = 6.61375632143793436117e-05,
1510 P4 = -1.65339022054652515390e-06,
1511 P5 = 4.13813679705723846039e-08,
1512 E = 2.718281828459045;
1514 static volatile double 1516 twom1000 = 9.33263618503218878990e-302,
1517 two1023 = 8.988465674311579539e307;
1519 double y, hi = 0.0, lo = 0.0, c, t, twopk;
1523 GET_HIGH_WORD(hx, x);
1524 xsb = (hx >> 31) & 1;
1528 if (hx >= 0x40862E42) {
1529 if (hx >= 0x7FF00000) {
1531 GET_LOW_WORD(lx, x);
1532 if (((hx & 0xFFFFF) | lx) != 0)
1535 return (xsb == 0) ? x : 0.0;
1537 if (x > o_threshold)
return huge * huge;
1538 if (x < u_threshold)
return twom1000 * twom1000;
1542 if (hx > 0x3FD62E42) {
1543 if (hx < 0x3FF0A2B2) {
1548 if (x == 1.0)
return E;
1549 hi = x - ln2HI[xsb];
1553 k =
static_cast<int>(invln2 * x + halF[xsb]);
1555 hi = x - t * ln2HI[0];
1558 STRICT_ASSIGN(
double, x, hi - lo);
1559 }
else if (hx < 0x3E300000) {
1560 if (huge + x > one)
return one + x;
1568 INSERT_WORDS(twopk, 0x3FF00000 + (k << 20), 0);
1570 INSERT_WORDS(twopk, 0x3FF00000 + ((k + 1000) << 20), 0);
1572 c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
1574 return one - ((x * c) / (c - 2.0) - x);
1576 y = one - ((lo - (x * c) / (2.0 - c)) - hi);
1579 if (k == 1024)
return y * 2.0 * two1023;
1582 return y * twopk * twom1000;
1603 double atanh(
double x) {
1604 static const double one = 1.0, huge = 1e300;
1605 static const double zero = 0.0;
1610 EXTRACT_WORDS(hx, lx, x);
1611 ix = hx & 0x7FFFFFFF;
1612 if ((ix | ((lx | -static_cast<int32_t>(lx)) >> 31)) > 0x3FF00000)
1613 return (x - x) / (x - x);
1614 if (ix == 0x3FF00000)
return x / zero;
1615 if (ix < 0x3E300000 && (huge + x) > zero)
return x;
1616 SET_HIGH_WORD(x, ix);
1617 if (ix < 0x3FE00000) {
1619 t = 0.5 * log1p(t + t * x / (one - x));
1621 t = 0.5 * log1p((x + x) / (one - x));
1679 double log(
double x) {
1681 ln2_hi = 6.93147180369123816490e-01,
1682 ln2_lo = 1.90821492927058770002e-10,
1683 two54 = 1.80143985094819840000e+16,
1684 Lg1 = 6.666666666666735130e-01,
1685 Lg2 = 3.999999999940941908e-01,
1686 Lg3 = 2.857142874366239149e-01,
1687 Lg4 = 2.222219843214978396e-01,
1688 Lg5 = 1.818357216161805012e-01,
1689 Lg6 = 1.531383769920937332e-01,
1690 Lg7 = 1.479819860511658591e-01;
1692 static const double zero = 0.0;
1693 static volatile double vzero = 0.0;
1695 double hfsq, f, s, z, R, w, t1, t2, dk;
1696 int32_t k, hx,
i, j;
1699 EXTRACT_WORDS(hx, lx, x);
1702 if (hx < 0x00100000) {
1703 if (((hx & 0x7FFFFFFF) | lx) == 0)
1704 return -two54 / vzero;
1705 if (hx < 0)
return (x - x) / zero;
1708 GET_HIGH_WORD(hx, x);
1710 if (hx >= 0x7FF00000)
return x + x;
1711 k += (hx >> 20) - 1023;
1713 i = (hx + 0x95F64) & 0x100000;
1714 SET_HIGH_WORD(x, hx | (
i ^ 0x3FF00000));
1717 if ((0x000FFFFF & (2 + hx)) < 3) {
1722 dk =
static_cast<double>(k);
1723 return dk * ln2_hi + dk * ln2_lo;
1726 R = f * f * (0.5 - 0.33333333333333333 * f);
1730 dk =
static_cast<double>(k);
1731 return dk * ln2_hi - ((R - dk * ln2_lo) - f);
1735 dk =
static_cast<double>(k);
1740 t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1741 t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
1747 return f - (hfsq - s * (hfsq + R));
1749 return dk * ln2_hi - ((hfsq - (s * (hfsq + R) + dk * ln2_lo)) - f);
1752 return f - s * (f - R);
1754 return dk * ln2_hi - ((s * (f - R) - dk * ln2_lo) - f);
1822 double log1p(
double x) {
1824 ln2_hi = 6.93147180369123816490e-01,
1825 ln2_lo = 1.90821492927058770002e-10,
1826 two54 = 1.80143985094819840000e+16,
1827 Lp1 = 6.666666666666735130e-01,
1828 Lp2 = 3.999999999940941908e-01,
1829 Lp3 = 2.857142874366239149e-01,
1830 Lp4 = 2.222219843214978396e-01,
1831 Lp5 = 1.818357216161805012e-01,
1832 Lp6 = 1.531383769920937332e-01,
1833 Lp7 = 1.479819860511658591e-01;
1835 static const double zero = 0.0;
1836 static volatile double vzero = 0.0;
1838 double hfsq, f, c, s, z, R, u;
1839 int32_t k, hx, hu, ax;
1841 GET_HIGH_WORD(hx, x);
1842 ax = hx & 0x7FFFFFFF;
1845 if (hx < 0x3FDA827A) {
1846 if (ax >= 0x3FF00000) {
1848 return -two54 / vzero;
1850 return (x - x) / (x - x);
1852 if (ax < 0x3E200000) {
1853 if (two54 + x > zero
1857 return x - x * x * 0.5;
1859 if (hx > 0 || hx <= static_cast<int32_t>(0xBFD2BEC4)) {
1865 if (hx >= 0x7FF00000)
return x + x;
1867 if (hx < 0x43400000) {
1868 STRICT_ASSIGN(
double, u, 1.0 + x);
1869 GET_HIGH_WORD(hu, u);
1870 k = (hu >> 20) - 1023;
1871 c = (k > 0) ? 1.0 - (u - x) : x - (u - 1.0);
1875 GET_HIGH_WORD(hu, u);
1876 k = (hu >> 20) - 1023;
1888 SET_HIGH_WORD(u, hu | 0x3FF00000);
1891 SET_HIGH_WORD(u, hu | 0x3FE00000);
1892 hu = (0x00100000 - hu) >> 2;
1903 return k * ln2_hi + c;
1906 R = hfsq * (1.0 - 0.66666666666666666 * f);
1910 return k * ln2_hi - ((R - (k * ln2_lo + c)) - f);
1915 z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 + z * (Lp6 + z * Lp7))))));
1917 return f - (hfsq - s * (hfsq + R));
1919 return k * ln2_hi - ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f);
1979 static const double Lg1 = 6.666666666666735130e-01,
1980 Lg2 = 3.999999999940941908e-01,
1981 Lg3 = 2.857142874366239149e-01,
1982 Lg4 = 2.222219843214978396e-01,
1983 Lg5 = 1.818357216161805012e-01,
1984 Lg6 = 1.531383769920937332e-01,
1985 Lg7 = 1.479819860511658591e-01;
1991 static inline double k_log1p(
double f) {
1992 double hfsq, s, z, R, w, t1, t2;
1997 t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
1998 t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
2001 return s * (hfsq + R);
2013 double log2(
double x) {
2015 two54 = 1.80143985094819840000e+16,
2016 ivln2hi = 1.44269504072144627571e+00,
2017 ivln2lo = 1.67517131648865118353e-10;
2019 static const double zero = 0.0;
2020 static volatile double vzero = 0.0;
2022 double f, hfsq, hi, lo, r, val_hi, val_lo, w, y;
2026 EXTRACT_WORDS(hx, lx, x);
2029 if (hx < 0x00100000) {
2030 if (((hx & 0x7FFFFFFF) | lx) == 0)
2031 return -two54 / vzero;
2032 if (hx < 0)
return (x - x) / zero;
2035 GET_HIGH_WORD(hx, x);
2037 if (hx >= 0x7FF00000)
return x + x;
2038 if (hx == 0x3FF00000 && lx == 0)
return zero;
2039 k += (hx >> 20) - 1023;
2041 i = (hx + 0x95F64) & 0x100000;
2042 SET_HIGH_WORD(x, hx | (
i ^ 0x3FF00000));
2044 y =
static_cast<double>(k);
2080 SET_LOW_WORD(hi, 0);
2081 lo = (f - hi) - hfsq + r;
2082 val_hi = hi * ivln2hi;
2083 val_lo = (lo + hi) * ivln2lo + lo * ivln2hi;
2087 val_lo += (y - w) + val_hi;
2090 return val_lo + val_hi;
2119 double log10(
double x) {
2121 two54 = 1.80143985094819840000e+16,
2122 ivln10 = 4.34294481903251816668e-01,
2123 log10_2hi = 3.01029995663611771306e-01,
2124 log10_2lo = 3.69423907715893078616e-13;
2126 static const double zero = 0.0;
2127 static volatile double vzero = 0.0;
2133 EXTRACT_WORDS(hx, lx, x);
2136 if (hx < 0x00100000) {
2137 if (((hx & 0x7FFFFFFF) | lx) == 0)
2138 return -two54 / vzero;
2139 if (hx < 0)
return (x - x) / zero;
2142 GET_HIGH_WORD(hx, x);
2143 GET_LOW_WORD(lx, x);
2145 if (hx >= 0x7FF00000)
return x + x;
2146 if (hx == 0x3FF00000 && lx == 0)
return zero;
2147 k += (hx >> 20) - 1023;
2149 i = (k & 0x80000000) >> 31;
2150 hx = (hx & 0x000FFFFF) | ((0x3FF -
i) << 20);
2152 SET_HIGH_WORD(x, hx);
2153 SET_LOW_WORD(x, lx);
2155 double z = y * log10_2lo + ivln10 * log(x);
2156 return z + y * log10_2hi;
2253 double expm1(
double x) {
2257 o_threshold = 7.09782712893383973096e+02,
2258 ln2_hi = 6.93147180369123816490e-01,
2259 ln2_lo = 1.90821492927058770002e-10,
2260 invln2 = 1.44269504088896338700e+00,
2263 Q1 = -3.33333333333331316428e-02,
2264 Q2 = 1.58730158725481460165e-03,
2265 Q3 = -7.93650757867487942473e-05,
2266 Q4 = 4.00821782732936239552e-06,
2267 Q5 = -2.01099218183624371326e-07;
2269 static volatile double huge = 1.0e+300;
2271 double y, hi, lo, c, t, e, hxs, hfx, r1, twopk;
2275 GET_HIGH_WORD(hx, x);
2276 xsb = hx & 0x80000000;
2280 if (hx >= 0x4043687A) {
2281 if (hx >= 0x40862E42) {
2282 if (hx >= 0x7FF00000) {
2284 GET_LOW_WORD(low, x);
2285 if (((hx & 0xFFFFF) | low) != 0)
2288 return (xsb == 0) ? x : -1.0;
2290 if (x > o_threshold)
return huge * huge;
2299 if (hx > 0x3FD62E42) {
2300 if (hx < 0x3FF0A2B2) {
2311 k = invln2 * x + ((xsb == 0) ? 0.5 : -0.5);
2313 hi = x - t * ln2_hi;
2316 STRICT_ASSIGN(
double, x, hi - lo);
2318 }
else if (hx < 0x3C900000) {
2320 return x - (t - (huge + x));
2328 r1 = one + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));
2330 e = hxs * ((r1 - t) / (6.0 - x * t));
2332 return x - (x * e - hxs);
2334 INSERT_WORDS(twopk, 0x3FF00000 + (k << 20), 0);
2335 e = (x * (e - c) - c);
2337 if (k == -1)
return 0.5 * (x - e) - 0.5;
2340 return -2.0 * (e - (x + 0.5));
2342 return one + 2.0 * (x - e);
2344 if (k <= -2 || k > 56) {
2350 y = y * 2.0 * 8.98846567431158e+307;
2357 SET_HIGH_WORD(t, 0x3FF00000 - (0x200000 >> k));
2361 SET_HIGH_WORD(t, ((0x3FF - k) << 20));
2370 double cbrt(
double x) {
2376 static const double P0 = 1.87595182427177009643,
2377 P1 = -1.88497979543377169875,
2378 P2 = 1.621429720105354466140,
2379 P3 = -0.758397934778766047437,
2380 P4 = 0.145996192886612446982;
2387 double r, s, t = 0.0, w;
2391 EXTRACT_WORDS(hx, low, x);
2392 sign = hx & 0x80000000;
2394 if (hx >= 0x7FF00000)
return (x + x);
2411 if (hx < 0x00100000) {
2412 if ((hx | low) == 0)
return (x);
2413 SET_HIGH_WORD(t, 0x43500000);
2415 GET_HIGH_WORD(high, t);
2416 INSERT_WORDS(t, sign | ((high & 0x7FFFFFFF) / 3 + B2), 0);
2418 INSERT_WORDS(t, sign | (hx / 3 + B1), 0);
2431 r = (t * t) * (t / x);
2432 t = t * ((P0 + r * (P1 + r * P2)) + ((r * r) * r) * (P3 + r * P4));
2445 u.bits = (u.bits + 0x80000000) & 0xFFFFFFFFC0000000ULL;
2452 r = (r - t) / (w + r);
2488 double sin(
double x) {
2489 double y[2], z = 0.0;
2493 GET_HIGH_WORD(ix, x);
2497 if (ix <= 0x3FE921FB) {
2498 return __kernel_sin(x, z, 0);
2499 }
else if (ix >= 0x7FF00000) {
2504 n = __ieee754_rem_pio2(x, y);
2507 return __kernel_sin(y[0], y[1], 1);
2509 return __kernel_cos(y[0], y[1]);
2511 return -__kernel_sin(y[0], y[1], 1);
2513 return -__kernel_cos(y[0], y[1]);
2547 double tan(
double x) {
2548 double y[2], z = 0.0;
2552 GET_HIGH_WORD(ix, x);
2556 if (ix <= 0x3FE921FB) {
2557 return __kernel_tan(x, z, 1);
2558 }
else if (ix >= 0x7FF00000) {
2563 n = __ieee754_rem_pio2(x, y);
2565 return __kernel_tan(y[0], y[1], 1 - ((n & 1) << 1));
2591 double cosh(
double x) {
2592 static const double KCOSH_OVERFLOW = 710.4758600739439;
2593 static const double one = 1.0, half = 0.5;
2594 static volatile double huge = 1.0e+300;
2599 GET_HIGH_WORD(ix, x);
2603 if (ix < 0x3FD62E43) {
2604 double t = expm1(fabs(x));
2607 if (ix < 0x3C800000)
return w;
2608 return one + (t * t) / (w + w);
2612 if (ix < 0x40360000) {
2613 double t = exp(fabs(x));
2614 return half * t + half / t;
2618 if (ix < 0x40862E42)
return half * exp(fabs(x));
2621 if (fabs(x) <= KCOSH_OVERFLOW) {
2622 double w = exp(half * fabs(x));
2623 double t = half * w;
2628 if (ix >= 0x7FF00000)
return x * x;
2653 double sinh(
double x) {
2654 static const double KSINH_OVERFLOW = 710.4758600739439,
2656 3.725290298461914e-9,
2657 LOG_MAXD = 709.7822265625;
2658 static const double shuge = 1.0e307;
2660 double h = (x < 0) ? -0.5 : 0.5;
2662 double ax = fabs(x);
2665 if (ax < TWO_M28)
return x;
2666 double t = expm1(ax);
2668 return h * (2 * t - t * t / (t + 1));
2670 return h * (t + t / (t + 1));
2673 if (ax < LOG_MAXD)
return h * exp(ax);
2676 if (ax <= KSINH_OVERFLOW) {
2677 double w = exp(0.5 * ax);
2709 double tanh(
double x) {
2710 static const volatile double tiny = 1.0e-300;
2711 static const double one = 1.0, two = 2.0, huge = 1.0e300;
2715 GET_HIGH_WORD(jx, x);
2716 ix = jx & 0x7FFFFFFF;
2719 if (ix >= 0x7FF00000) {
2721 return one / x + one;
2723 return one / x - one;
2727 if (ix < 0x40360000) {
2728 if (ix < 0x3E300000) {
2729 if (huge + x > one)
return x;
2731 if (ix >= 0x3FF00000) {
2732 t = expm1(two * fabs(x));
2733 z = one - two / (t + two);
2735 t = expm1(-two * fabs(x));
2742 return (jx >= 0) ? z : -z;