| 41 | #endif |
| 42 | |
| 43 | struct DiyFp { |
| 44 | DiyFp() : f(), e() {} |
| 45 | |
| 46 | DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {} |
| 47 | |
| 48 | explicit DiyFp(double d) { |
| 49 | union { |
| 50 | double d; |
| 51 | uint64_t u64; |
| 52 | } u = { d }; |
| 53 | |
| 54 | int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize); |
| 55 | uint64_t significand = (u.u64 & kDpSignificandMask); |
| 56 | if (biased_e != 0) { |
| 57 | f = significand + kDpHiddenBit; |
| 58 | e = biased_e - kDpExponentBias; |
| 59 | } |
| 60 | else { |
| 61 | f = significand; |
| 62 | e = kDpMinExponent + 1; |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | DiyFp operator-(const DiyFp& rhs) const { |
| 67 | return DiyFp(f - rhs.f, e); |
| 68 | } |
| 69 | |
| 70 | DiyFp operator*(const DiyFp& rhs) const { |
| 71 | #if defined(_MSC_VER) && defined(_M_AMD64) |
| 72 | uint64_t h; |
| 73 | uint64_t l = _umul128(f, rhs.f, &h); |
| 74 | if (l & (uint64_t(1) << 63)) // rounding |
| 75 | h++; |
| 76 | return DiyFp(h, e + rhs.e + 64); |
| 77 | #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) |
| 78 | __extension__ typedef unsigned __int128 uint128; |
| 79 | uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f); |
| 80 | uint64_t h = static_cast<uint64_t>(p >> 64); |
| 81 | uint64_t l = static_cast<uint64_t>(p); |
| 82 | if (l & (uint64_t(1) << 63)) // rounding |
| 83 | h++; |
| 84 | return DiyFp(h, e + rhs.e + 64); |
| 85 | #else |
| 86 | const uint64_t M32 = 0xFFFFFFFF; |
| 87 | const uint64_t a = f >> 32; |
| 88 | const uint64_t b = f & M32; |
| 89 | const uint64_t c = rhs.f >> 32; |
| 90 | const uint64_t d = rhs.f & M32; |
| 91 | const uint64_t ac = a * c; |
| 92 | const uint64_t bc = b * c; |
| 93 | const uint64_t ad = a * d; |
| 94 | const uint64_t bd = b * d; |
| 95 | uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32); |
| 96 | tmp += 1U << 31; /// mult_round |
| 97 | return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64); |
| 98 | #endif |
| 99 | } |
| 100 |
no outgoing calls
no test coverage detected