From feef4dd9aa270a969e4686db1d277be44e437565 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Thu, 1 Jan 2026 13:34:42 -0700 Subject: [PATCH] :bug: Fix fallback implementation of `bit_ceil` Problem: - The fallback implementation of `bit_ceil` is implemented incorrectly. In particular it returns the wrong values for exact powers of 2. Solution: - Fix the calculation: subtracting 1 before calculating the bit width is appropriate. Notes: - Thanks to Walter Brown for pointing out this issue in private correspondence. - Undoubtedly, this was missed because of issue #117. --- include/stdx/bit.hpp | 2 +- test/bit.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/stdx/bit.hpp b/include/stdx/bit.hpp index 6fdf733..1142717 100644 --- a/include/stdx/bit.hpp +++ b/include/stdx/bit.hpp @@ -223,7 +223,7 @@ template if (x <= 1U) { return 1U; } - return T(1U << bit_width(x)); + return T(1U << bit_width(x - 1U)); } template diff --git a/test/bit.cpp b/test/bit.cpp index 982b5d5..d134d32 100644 --- a/test/bit.cpp +++ b/test/bit.cpp @@ -160,6 +160,9 @@ TEMPLATE_TEST_CASE("bit_ceil", "[bit]", std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t) { STATIC_REQUIRE(stdx::bit_ceil(TestType{}) == 1); STATIC_REQUIRE(stdx::bit_ceil(TestType{1u}) == 1); + STATIC_REQUIRE(stdx::bit_ceil(TestType{3u}) == 4); + STATIC_REQUIRE(stdx::bit_ceil(TestType{4u}) == 4); + STATIC_REQUIRE(stdx::bit_ceil(TestType{5u}) == 8); STATIC_REQUIRE(stdx::bit_ceil(TestType{45u}) == 64); } @@ -167,6 +170,9 @@ TEMPLATE_TEST_CASE("bit_floor", "[bit]", std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t) { STATIC_REQUIRE(stdx::bit_floor(TestType{}) == 0); STATIC_REQUIRE(stdx::bit_floor(TestType{1u}) == 1); + STATIC_REQUIRE(stdx::bit_floor(TestType{3u}) == 2); + STATIC_REQUIRE(stdx::bit_floor(TestType{4u}) == 4); + STATIC_REQUIRE(stdx::bit_floor(TestType{5u}) == 4); STATIC_REQUIRE(stdx::bit_floor(TestType{45u}) == 32); }