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