13 inline constexpr auto nan_mix(
auto x,
auto y)
noexcept {
return ((x + 0.0L) + (y + 0)); }
15 template <
typename A,
typename B>
16 constexpr void extract_words(A& high, B& low,
double d)
noexcept
18 low = std::bit_cast<uint64_t>(d) & 0xFFFFFFFF;
19 high = (std::bit_cast<uint64_t>(d) >> 32LL) & 0xFFFFFFFF;
23 constexpr void get_high_word(A& high,
double d)
noexcept
25 high = (std::bit_cast<uint64_t>(d) >> 32LL) & 0xFFFFFFFF;
29 constexpr void get_low_word(A& low,
double d)
noexcept
31 low = std::bit_cast<uint64_t>(d) & 0xFFFFFFFF;
34 template <
typename A,
typename B>
35 constexpr void insert_words(
double& d, A high, B low)
noexcept
37 const auto bits =
static_cast<uint64_t
>(std::bit_cast<uint32_t>(low)) | (
static_cast<uint64_t
>(std::bit_cast<uint32_t>(high)) << 32ULL);
38 d = std::bit_cast<double>(bits);
42 constexpr void set_high_word(
double& d, A i)
noexcept
44 uint32_t low = 0, high = 0;
45 ::ghassanpl::cem::detail::extract_words(high, low, d);
46 ::ghassanpl::cem::detail::insert_words(d, i, low);
50 constexpr void set_low_word(
double& d, A i)
noexcept
52 uint32_t low = 0, high = 0;
53 ::ghassanpl::cem::detail::extract_words(high, low, d);
54 ::ghassanpl::cem::detail::insert_words(d, high, i);
57 static constexpr double bp[] = { 1.0, 1.5 };
58 static constexpr double dp_h[] = { 0.0, 5.84962487220764160156e-01 };
59 static constexpr double dp_l[] = { 0.0, 1.35003920212974897128e-08 };
60 static constexpr double zero = 0.0;
61 static constexpr double half = 0.5;
62 static constexpr double qrtr = 0.25;
63 static constexpr double thrd = 3.3333333333333331e-01;
64 static constexpr double one = 1.0;
65 static constexpr double two = 2.0;
66 static constexpr double two53 = 9007199254740992.0;
67 static constexpr double huge = 1.0e300;
68 static constexpr double tiny = 1.0e-300;
69 static constexpr double L1 = 5.99999999999994648725e-01;
70 static constexpr double L2 = 4.28571428578550184252e-01;
71 static constexpr double L3 = 3.33333329818377432918e-01;
72 static constexpr double L4 = 2.72728123808534006489e-01;
73 static constexpr double L5 = 2.30660745775561754067e-01;
74 static constexpr double L6 = 2.06975017800338417784e-01;
75 static constexpr double P1 = 1.66666666666666019037e-01;
76 static constexpr double P2 = -2.77777777770155933842e-03;
77 static constexpr double P3 = 6.61375632143793436117e-05;
78 static constexpr double P4 = -1.65339022054652515390e-06;
79 static constexpr double P5 = 4.13813679705723846039e-08;
80 static constexpr double lg2 = 6.93147180559945286227e-01;
81 static constexpr double lg2_h = 6.93147182464599609375e-01;
82 static constexpr double lg2_l = -1.90465429995776804525e-09;
83 static constexpr double ovt = 8.0085662595372944372e-0017;
84 static constexpr double cp = 9.61796693925975554329e-01;
85 static constexpr double cp_h = 9.61796700954437255859e-01;
86 static constexpr double cp_l = -7.02846165095275826516e-09;
87 static constexpr double ivln2 = 1.44269504088896338700e+00;
88 static constexpr double ivln2_h = 1.44269502162933349609e+00;
89 static constexpr double ivln2_l = 1.92596299112661746887e-08;
94 int32_t sign = (int)0x80000000;
95 int32_t ix0, s0, q, m, t, i;
96 uint32_t r, t1, s1, ix1, q1;
98 extract_words(ix0, ix1, x);
101 if ((ix0 & 0x7ff00000) == 0x7ff00000)
103 if (x == std::numeric_limits<double>::infinity())
105 return std::numeric_limits<double>::quiet_NaN();
110 if (((ix0 & (~sign)) | ix1) == 0)
113 return std::numeric_limits<double>::quiet_NaN();
125 for (i = 0; (ix0 & 0x00100000) == 0; i++)
128 ix0 |= (ix1 >> (32 - i));
132 ix0 = (ix0 & 0x000fffff) | 0x00100000;
135 ix0 += ix0 + ((ix1 & sign) >> 31);
141 ix0 += ix0 + ((ix1 & sign) >> 31);
143 q = q1 = s0 = s1 = 0;
155 ix0 += ix0 + ((ix1 & sign) >> 31);
165 if ((t < ix0) || ((t == ix0) && (t1 <= ix1)))
168 if (((t1 & sign) == sign) && (s1 & sign) == 0)
176 ix0 += ix0 + ((ix1 & sign) >> 31);
182 if ((ix0 | ix1) != 0)
188 if (q1 == (uint32_t)0xffffffff)
195 if (q1 == (uint32_t)0xfffffffe)
203 ix0 = (q >> 1) + 0x3fe00000;
208 insert_words(z, ix0, ix1);
212 constexpr double scalbn(
double x,
int n)
noexcept
232 y *= 0x1p-1022 * 0x1p53;
236 y *= 0x1p-1022 * 0x1p53;
242 x = y * std::bit_cast<double>((uint64_t)(0x3ff + n) << 52);
246 constexpr double pow_impl(
double x,
double y)
noexcept
248 double z, ax, z_h, z_l, p_h, p_l;
249 double y1, t1, t2, r, s, t, u, v, w;
250 int32_t i, j, k, yisint, n;
251 int32_t hx, hy, ix, iy;
254 extract_words(hx, lx, x);
255 extract_words(hy, ly, y);
256 ix = hx & 0x7fffffff;
257 iy = hy & 0x7fffffff;
264 if (hx == 0x3ff00000 && lx == 0)
268 if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) ||
269 iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0)))
270 return std::numeric_limits<double>::quiet_NaN();
280 if (iy >= 0x43400000)
282 else if (iy >= 0x3ff00000)
284 k = (iy >> 20) - 0x3ff;
288 if (((uint32_t)j << (52 - k)) == ly)
289 yisint = 2 - (j & 1);
294 if ((j << (20 - k)) == iy)
295 yisint = 2 - (j & 1);
303 if (iy == 0x7ff00000)
305 if (((ix - 0x3ff00000) | lx) == 0)
307 else if (ix >= 0x3ff00000)
308 return (hy >= 0) ? y :
zero;
310 return (hy < 0) ? -y :
zero;
312 if (iy == 0x3ff00000)
319 if (hy == 0x40000000)
321 if (hy == 0x3fe00000)
332 if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000)
339 if (((ix - 0x3ff00000) | yisint) == 0)
341 z = (z - z) / (z - z);
343 else if (yisint == 1)
354 n = ((uint32_t)hx >> 31) - 1;
357 if ((n | yisint) == 0)
358 return std::numeric_limits<double>::quiet_NaN();
361 if ((n | (yisint - 1)) == 0)
369 if (ix <= 0x3fefffff)
370 return (hy < 0) ?
huge *
huge : tiny * tiny;
371 if (ix >= 0x3ff00000)
372 return (hy > 0) ?
huge *
huge : tiny * tiny;
376 return (hy < 0) ? s *
huge *
huge : s * tiny * tiny;
378 return (hy > 0) ? s *
huge *
huge : s * tiny * tiny;
382 w = (t * t) * (half - t * (thrd - t * qrtr));
391 double ss, s2, s_h, s_l, t_h, t_l;
398 get_high_word(ix, ax);
400 n += ((ix) >> 20) - 0x3ff;
406 else if (j < 0xBB67A)
414 set_high_word(ax, ix);
418 v =
one / (ax + bp[k]);
421 set_low_word(s_h, 0);
424 set_high_word(t_h, ((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18));
425 t_l = ax - (t_h - bp[k]);
426 s_l = v * ((u - s_h * t_h) - s_h * t_l);
429 r = s2 * s2 * (L1 + s2 * (
L2 + s2 * (
L3 + s2 * (
L4 + s2 * (
L5 + s2 *
L6)))));
430 r += s_l * (s_h + ss);
433 set_low_word(t_h, 0);
434 t_l = r - ((t_h - 3) - s2);
437 v = s_l * t_h + t_l * ss;
440 set_low_word(p_h, 0);
446 t1 = (((z_h + z_l) + dp_h[k]) + t);
448 t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
454 p_l = (y - y1) * t1 + y * t2;
457 extract_words(j, i, z);
460 if (((j - 0x40900000) | i) != 0)
464 if (p_l +
ovt > z - p_h)
468 else if ((j & 0x7fffffff) >= 0x4090cc00)
470 if (((j - 0xc090cc00) | i) != 0)
471 return s * tiny * tiny;
475 return s * tiny * tiny;
482 k = (i >> 20) - 0x3ff;
486 n = j + (0x00100000 >> (k + 1));
487 k = ((n & 0x7fffffff) >> 20) - 0x3ff;
489 set_high_word(t, n & ~(0x000fffff >> k));
490 n = ((n & 0x000fffff) | 0x00100000) >> (20 - k);
498 v = (p_l - (t - p_h)) *
lg2 + t *
lg2_l;
502 t1 = z - t * (
P1 + t * (
P2 + t * (
P3 + t * (
P4 + t *
P5))));
503 r = (z * t1) / (t1 - two) - (w + z * w);