| 8 | #include <limits> |
| 9 | |
| 10 | double DecodeDouble(uint64_t v) noexcept { |
| 11 | static constexpr double NANVAL = std::numeric_limits<double>::quiet_NaN(); |
| 12 | static constexpr double INFVAL = std::numeric_limits<double>::infinity(); |
| 13 | double sign = 1.0; |
| 14 | if (v & 0x8000000000000000) { |
| 15 | sign = -1.0; |
| 16 | v ^= 0x8000000000000000; |
| 17 | } |
| 18 | // Zero |
| 19 | if (v == 0) return copysign(0.0, sign); |
| 20 | // Infinity |
| 21 | if (v == 0x7ff0000000000000) return copysign(INFVAL, sign); |
| 22 | // Other numbers |
| 23 | int exp = (v & 0x7FF0000000000000) >> 52; |
| 24 | uint64_t man = v & 0xFFFFFFFFFFFFF; |
| 25 | if (exp == 2047) { |
| 26 | // NaN |
| 27 | return NANVAL; |
| 28 | } else if (exp == 0) { |
| 29 | // Subnormal |
| 30 | return copysign(ldexp((double)man, -1074), sign); |
| 31 | } else { |
| 32 | // Normal |
| 33 | return copysign(ldexp((double)(man + 0x10000000000000), -1075 + exp), sign); |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | uint64_t EncodeDouble(double f) noexcept { |
| 38 | int cls = std::fpclassify(f); |
no outgoing calls