5#ifndef LINE_UTIL_FDLIBM_H
6#define LINE_UTIL_FDLIBM_H
57inline int hi_word(
double x) {
59 std::memcpy(&i, &x,
sizeof i);
60 return static_cast<int>(i >> 32);
63inline void set_hi_word(
double* x,
int hi) {
65 std::memcpy(&i, x,
sizeof i);
66 i = (
static_cast<std::int64_t
>(hi) << 32) | (i & 0xffffffffLL);
67 std::memcpy(x, &i,
sizeof i);
81inline double log1p(
double x) {
82 static const double ln2_hi = 6.93147180369123816490e-01;
83 static const double ln2_lo = 1.90821492927058770002e-10;
84 static const double two54 = 1.80143985094819840000e+16;
85 static const double Lp1 = 6.666666666666735130e-01;
86 static const double Lp2 = 3.999999999940941908e-01;
87 static const double Lp3 = 2.857142874366239149e-01;
88 static const double Lp4 = 2.222219843214978396e-01;
89 static const double Lp5 = 1.818357216161805012e-01;
90 static const double Lp6 = 1.531383769920937332e-01;
91 static const double Lp7 = 1.479819860511658591e-01;
93 double hfsq, f = 0.0, c = 0.0, s, z, R, u;
94 int k, hx, hu = 0, ax;
96 hx = detail::hi_word(x);
99 if (hx < 0x3FDA827A) {
100 if (ax >= 0x3ff00000) {
101 if (x == -1.0)
return -two54 / 0.0;
102 return (x - x) / (x - x);
104 if (ax < 0x3e200000) {
105 if (two54 + x > 0.0 && ax < 0x3c900000)
return x;
106 return x - x * x * 0.5;
108 if (hx > 0 || hx <=
static_cast<int>(0xbfd2bec3)) {
114 if (hx >= 0x7ff00000)
return x + x;
116 if (hx < 0x43400000) {
118 hu = detail::hi_word(u);
119 k = (hu >> 20) - 1023;
121 c = (k > 0) ? 1.0 - (u - x) : x - (u - 1.0);
125 hu = detail::hi_word(u);
126 k = (hu >> 20) - 1023;
131 detail::set_hi_word(&u, hu | 0x3ff00000);
134 detail::set_hi_word(&u, hu | 0x3fe00000);
135 hu = (0x00100000 - hu) >> 2;
143 if (k == 0)
return 0.0;
145 return k * ln2_hi + c;
147 R = hfsq * (1.0 - 0.66666666666666666 * f);
148 if (k == 0)
return f - R;
149 return k * ln2_hi - ((R - (k * ln2_lo + c)) - f);
153 R = z * (Lp1 + z * (Lp2 + z * (Lp3 + z * (Lp4 + z * (Lp5 + z * (Lp6 + z * Lp7))))));
154 if (k == 0)
return f - (hfsq - s * (hfsq + R));
155 return k * ln2_hi - ((hfsq - (s * (hfsq + R) + (k * ln2_lo + c))) - f);