std::bit_floor - cppreference.com
Namespaces
Variants

std::bit_floor

From cppreference.com
 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
Integer comparison functions
(C++20)(C++20)(C++20)    
(C++20)
Swap and type operations
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Common vocabulary types
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
 
Defined in header <bit>
template< class T >
constexpr T bit_floor( T x ) noexcept;
(since C++20)

If x is not zero, calculates the largest integral power of two that is not greater than x. If x is zero, returns zero.

Parameters

x - a value to compare with
Type requirements
T - must be an unsigned integer type (that is, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, or an extended unsigned integer type) in order to participate in overload resolution.

Return value

Zero if x is zero; otherwise, the largest integral power of two that is not greater than x.

Notes

Prior to P1956R1, the proposed name for this function template was floor2.

Feature-test macro Value Std Feature
__cpp_lib_int_pow2 202002L (C++20) Integral power-of-2 operations

Possible implementation

template<typename T, typename ... U>
concept neither = (!std::same_as<T, U> && ...);

template<std::unsigned_integral T>
    requires neither<T, bool, char, char8_t, char16_t, char32_t, wchar_t>
constexpr T bit_floor(T x) noexcept
{
    if (x != 0)
        return T{1} << (std::bit_width(x) - 1);
    return 0;
}

Example

#include <bit>
#include <cstdio>
#include <print>

int main()
{
    for (unsigned x{}; x != 9; ++x)
    {
        if (std::has_single_bit(x))
            std::putchar('\n');

        std::print("bit_floor({:04b}) = {:04b}\n", x, std::bit_floor(x));
    }
}

Output:

bit_floor(0000) = 0000

bit_floor(0001) = 0001

bit_floor(0010) = 0010
bit_floor(0011) = 0010

bit_floor(0100) = 0100
bit_floor(0101) = 0100
bit_floor(0110) = 0100
bit_floor(0111) = 0100

bit_floor(1000) = 1000

See also