| 1637 | // Normalizes the value converted from double and multiplied by (1 << SHIFT). |
| 1638 | template <int SHIFT = 0, typename F> |
| 1639 | FMT_CONSTEXPR auto normalize(basic_fp<F> value) -> basic_fp<F> { |
| 1640 | // Handle subnormals. |
| 1641 | const auto implicit_bit = F(1) << num_significand_bits<double>(); |
| 1642 | const auto shifted_implicit_bit = implicit_bit << SHIFT; |
| 1643 | while ((value.f & shifted_implicit_bit) == 0) { |
| 1644 | value.f <<= 1; |
| 1645 | --value.e; |
| 1646 | } |
| 1647 | // Subtract 1 to account for hidden bit. |
| 1648 | const auto offset = basic_fp<F>::num_significand_bits - |
| 1649 | num_significand_bits<double>() - SHIFT - 1; |
| 1650 | value.f <<= offset; |
| 1651 | value.e -= offset; |
| 1652 | return value; |
| 1653 | } |
| 1654 | |
| 1655 | // Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking. |
| 1656 | FMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t { |