Skip to content

Commit

Permalink
Add countl_zero function
Browse files Browse the repository at this point in the history
Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
  • Loading branch information
phprus committed Nov 30, 2022
1 parent 115ca96 commit 81c5a48
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
12 changes: 11 additions & 1 deletion include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,16 @@ inline auto bit_cast(const From& from) -> To {
return result;
}

FMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int {
#ifdef FMT_BUILTIN_CLZ
if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n);
#endif
int lz = 0;
constexpr uint32_t msb_mask = 1u << (num_bits<uint32_t>() - 1);
for (; (n & msb_mask) == 0; n <<= 1) lz++;
return lz;
}

FMT_INLINE void assume(bool condition) {
(void)condition;
#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION
Expand Down Expand Up @@ -3149,7 +3159,7 @@ FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision,
const auto leading_mask = carrier_uint(0xF) << leading_shift;
const auto leading_xdigit =
static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
if (leading_xdigit > 1) f.e -= (32 - FMT_BUILTIN_CLZ(leading_xdigit) - 1);
if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);

int print_xdigits = num_xdigits - 1;
if (precision >= 0 && print_xdigits > precision) {
Expand Down
10 changes: 10 additions & 0 deletions test/format-impl-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,16 @@ TEST(format_impl_test, count_digits) {
test_count_digits<uint64_t>();
}

TEST(format_impl_test, countl_zero) {
constexpr auto num_bits = fmt::detail::num_bits<uint32_t>();
uint32_t n = 1u;
for (int i = 1; i < num_bits - 1; i++) {
n <<= 1;
EXPECT_EQ(fmt::detail::countl_zero(n - 1), num_bits - i);
EXPECT_EQ(fmt::detail::countl_zero(n), num_bits - i - 1);
}
}

#if FMT_USE_FLOAT128
TEST(format_impl_test, write_float128) {
auto s = std::string();
Expand Down

0 comments on commit 81c5a48

Please sign in to comment.