Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
| 440 | |
| 441 | // Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking. |
| 442 | inline uint64_t multiply(uint64_t lhs, uint64_t rhs) { |
| 443 | #if FMT_USE_INT128 |
| 444 | auto product = static_cast<__uint128_t>(lhs) * rhs; |
| 445 | auto f = static_cast<uint64_t>(product >> 64); |
| 446 | return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f; |
| 447 | #else |
| 448 | // Multiply 32-bit parts of significands. |
| 449 | uint64_t mask = (1ULL << 32) - 1; |
| 450 | uint64_t a = lhs >> 32, b = lhs & mask; |
| 451 | uint64_t c = rhs >> 32, d = rhs & mask; |
| 452 | uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d; |
| 453 | // Compute mid 64-bit of result and round. |
| 454 | uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31); |
| 455 | return ac + (ad >> 32) + (bc >> 32) + (mid >> 32); |
| 456 | #endif |
| 457 | } |
| 458 | |
| 459 | inline fp operator*(fp x, fp y) { return {multiply(x.f, y.f), x.e + y.e + 64}; } |
| 460 |
no outgoing calls
no test coverage detected