66 inline void umul192 (uint64_t hi, uint64_t lo, uint64_t significand, uint64_t& high, uint64_t& middle, uint64_t& low)
noexcept
68 #if defined(__SIZEOF_INT128__)
69 __uint128_t h =
static_cast <__uint128_t
> (hi) * significand;
70 __uint128_t l =
static_cast <__uint128_t
> (lo) * significand;
71 __uint128_t s = h + (l >> 64);
73 high =
static_cast <uint64_t
> (s >> 64);
74 middle =
static_cast <uint64_t
> (s);
75 low =
static_cast <uint64_t
> (l);
77 uint64_t hi_hi, hi_lo, lo_hi, lo_lo;
79 uint64_t m_lo =
static_cast <uint32_t
> (significand);
80 uint64_t m_hi = significand >> 32;
81 uint64_t p0 = (hi & 0xFFFFFFFF) * m_lo;
82 uint64_t p1 = (hi >> 32) * m_lo;
83 uint64_t p2 = (hi & 0xFFFFFFFF) * m_hi;
84 uint64_t p3 = (hi >> 32) * m_hi;
85 uint64_t carry = (p0 >> 32) + (p1 & 0xFFFFFFFF) + (p2 & 0xFFFFFFFF);
86 hi_lo = (carry << 32) | (p0 & 0xFFFFFFFF);
87 hi_hi = (carry >> 32) + (p1 >> 32) + (p2 >> 32) + p3;
89 p0 = (lo & 0xFFFFFFFF) * m_lo;
90 p1 = (lo >> 32) * m_lo;
91 p2 = (lo & 0xFFFFFFFF) * m_hi;
92 p3 = (lo >> 32) * m_hi;
93 carry = (p0 >> 32) + (p1 & 0xFFFFFFFF) + (p2 & 0xFFFFFFFF);
94 lo_lo = (carry << 32) | (p0 & 0xFFFFFFFF);
95 lo_hi = (carry >> 32) + (p1 >> 32) + (p2 >> 32) + p3;
98 middle = hi_lo + lo_hi;
99 high = hi_hi + (middle < hi_lo ? 1 : 0);
103 inline bool strtodFast (
bool negative, uint64_t significand, int64_t exponent,
double& value)
noexcept
105 static constexpr double pow10[] = {
106 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
107 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21,
111 value =
static_cast <double> (significand);
113 if (
unlikely((exponent > 22) && (exponent < (22 + 16))))
115 value *= pow10[exponent - 22];
119 if (
likely ((exponent >= -22) && (exponent <= 22) && (value <= 9007199254740991.0)))
121 value = (exponent < 0) ? (value / pow10[-exponent]) : (value * pow10[exponent]);
122 value = negative ? -value : value;
128 value = negative ? -0.0 : 0.0;
132 if (
unlikely (exponent < -325 || exponent > 308))
137 uint64_t high, middle, low;
139 umul192 (power.
hi, power.
lo, significand, high, middle, low);
140 int64_t exp = ((exponent * 217706) >> 16) + 1087;
145 lz = __builtin_clzll (high);
148 else if (middle != 0)
150 lz = __builtin_clzll (middle);
158 if (
unlikely (exp <= 0 || exp >= 2047))
170 high = (high << lz) | (middle >> (64 - lz));
174 middle |= (low != 0);
176 uint64_t mant = (high >> 11) & 0xFFFFFFFFFFFFF;
177 uint64_t bits = (
static_cast <uint64_t
> (exp) << 52) | mant;
178 uint64_t frac = high & 0x7FF;
180 bool roundUp = ((frac > 0x400) |
181 ((frac == 0x400) && ((middle != 0) || (mant & 1))) |
182 ((frac == 0x3FF) && ((middle != 0))));
185 bits |= (
static_cast <uint64_t
> (negative) << 63);
186 std::memcpy (&value, &bits,
sizeof (
double));
201 inline const char *
atod (
View& view,
double& value)
203 auto beg = view.
data ();
205 uint64_t significand = 0;
207 bool neg = view.
getIf (
'-');
209 if (view.
getIf (
'0'))
218 significand = view.
get () -
'0';
223 uint64_t next = (10 * significand) + (view.
get () -
'0');
242 value = neg ? -std::numeric_limits <double>::infinity () : std::numeric_limits <double>::infinity ();
247 value = neg ? -std::numeric_limits <double>::quiet_NaN () : std::numeric_limits <double>::quiet_NaN ();
255 int64_t exponent = 0;
257 if (view.
getIf (
'.'))
264 significand = (10 * significand) + (view.
get () -
'0');
265 if (significand || digits) ++digits;
270 uint64_t next = (10 * significand) + (view.
get () -
'0');
276 if (significand || digits) ++digits;
287 negExp = (view.
get () ==
'-');
295 int64_t exp = view.
get () -
'0';
301 exp = (10 * exp) + (view.
get () -
'0');
309 exponent += (negExp ? -exp : exp);
312 if (
likely (digits <= 19))
314 if (
strtodFast (neg, significand, exponent, value))