Commit 4c212881 authored by Milo Yip's avatar Milo Yip

Add 32-bit support for custom strtod

parent 855da06d
...@@ -299,17 +299,36 @@ private: ...@@ -299,17 +299,36 @@ private:
static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) { static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) {
#if defined(_MSC_VER) && defined(_M_AMD64) #if defined(_MSC_VER) && defined(_M_AMD64)
uint64_t low = _umul128(a, b, outHigh); uint64_t low = _umul128(a, b, outHigh);
uint64_t outLow = low + k; low += k;
if (outLow < low) if (low < k)
(*outHigh)++; (*outHigh)++;
return outLow; return low;
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
unsigned __int128 p = static_cast<unsigned __int128>(a) * static_cast<unsigned __int128>(b); unsigned __int128 p = static_cast<unsigned __int128>(a) * static_cast<unsigned __int128>(b);
p += k; p += k;
*outHigh = p >> 64; *outHigh = p >> 64;
return static_cast<uint64_t>(p); return static_cast<uint64_t>(p);
#else #else
// TODO const uint64_t a0 = a & 0xFFFFFFFF;
const uint64_t a1 = a >> 32;
const uint64_t b0 = b & 0xFFFFFFFF;
const uint64_t b1 = b >> 32;
uint64_t x0 = a0 * b0;
uint64_t x1 = a0 * b1;
uint64_t x2 = a1 * b0;
uint64_t x3 = a1 * b1;
x1 += (x0 >> 32); // can't give carry
x1 += x2;
if (x1 < x2)
x3 += (static_cast<uint64_t>(1) << 32);
uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF);
uint64_t hi = x3 + (x1 >> 32);
lo += k;
if (lo < k)
hi++;
*outHigh = hi;
return lo;
#endif #endif
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment