static double convert_to_double_core(const uint64_t* limb, int sz, int exp, bool sign) { uint64_t lsbits = 0; for (int i = 0; i < sz - 1; ++i) lsbits |= limb[i]; uint64_t msw = limb[sz-1]; lsbits |= msw & 1; // Don't use uint64_t -> double conversion, because there are compilers, // in particular MS VisualC++, that for some versions on some platform (I saw it on VS2013/x64/avx) // does not implement this conversion well when the argument is >= 2^63, i.e. exactly in our case. // On the other hand int64_t -> double conversion appears to be robust on all platforms that I tested int64_t m = msw >> 1; if (lsbits) m |= 1; if (sign) m = -m; return ldexp(m, exp-62); }