13inline int32_t hi_word(
double x){ uint64_t u; std::memcpy(&u,&x,8);
return (int32_t)(uint32_t)(u>>32); }
14inline uint32_t lo_word(
double x){ uint64_t u; std::memcpy(&u,&x,8);
return (uint32_t)u; }
15inline void set_hi_word(
double& x, uint32_t hi){ uint64_t u; std::memcpy(&u,&x,8);
16 u = (u & 0x00000000ffffffffULL) | ((uint64_t)hi<<32); std::memcpy(&x,&u,8); }
22inline double rnd(
double v) {
volatile double t = v;
return t; }
24inline double log(
double x) {
28#pragma clang fp contract(off)
31 ln2_hi = 6.93147180369123816490e-01,
32 ln2_lo = 1.90821492927058770002e-10,
33 two54 = 1.80143985094819840000e+16,
34 Lg1 = 6.666666666666735130e-01,
35 Lg2 = 3.999999999940941908e-01,
36 Lg3 = 2.857142874366239149e-01,
37 Lg4 = 2.222219843214978396e-01,
38 Lg5 = 1.818357216161805012e-01,
39 Lg6 = 1.531383769920937332e-01,
40 Lg7 = 1.479819860511658591e-01,
43 double hfsq,f,s,z,R,w,t1,t2,dk;
51 if (hx < 0x00100000) {
55 if (((hx & 0x7fffffff) | lx) == 0) {
56 return -std::numeric_limits<double>::infinity();
59 return std::numeric_limits<double>::quiet_NaN();
64 if (hx >= 0x7ff00000) {
return x+x; }
67 i = (hx + 0x95f64) & 0x100000;
68 set_hi_word(x, (uint32_t)(hx | (i ^ 0x3ff00000)));
71 if ((0x000fffff & (2+hx)) < 3) {
73 if (k == 0) {
return zero; }
74 dk = (double)k;
return rnd(dk*ln2_hi) + rnd(dk*ln2_lo);
76 R = rnd(rnd(f*f)*rnd(0.5 - rnd(0.33333333333333333*f)));
77 if (k == 0) {
return f-R; }
78 dk = (double)k;
return rnd(dk*ln2_hi) - (rnd(R - rnd(dk*ln2_lo)) - f);
86 t1 = rnd(w*rnd(Lg2 + rnd(w*rnd(Lg4 + rnd(w*Lg6)))));
87 t2 = rnd(z*rnd(Lg1 + rnd(w*rnd(Lg3 + rnd(w*rnd(Lg5 + rnd(w*Lg7)))))));
92 if (k == 0) {
return f - rnd(hfsq - rnd(s*(hfsq+R))); }
93 return rnd(dk*ln2_hi) - (rnd(hfsq - rnd(rnd(s*(hfsq+R)) + rnd(dk*ln2_lo))) - f);
95 if (k == 0) {
return f - rnd(s*(f-R)); }
96 return rnd(dk*ln2_hi) - (rnd(rnd(s*(f-R)) - rnd(dk*ln2_lo)) - f);