Difference between revisions of "cpp/numeric/bit ceil"
From cppreference.com
(+= gcc/clang libs links to possible implementation) |
(→Possible implementation: adopt the impl in libc++) |
||
Line 41: | Line 41: | ||
===Possible implementation=== | ===Possible implementation=== | ||
See possible implementations in [https://github.com/gcc-mirror/gcc/blob/62c25d7adb1a5664982449dda0e7f9ca63cf4735/libstdc%2B%2B-v3/include/std/bit#L217-L248 libstdc++ (gcc)] and [https://github.com/llvm-mirror/libcxx/blob/78d6a7767ed57b50122a161b91f59f19c9bd0d19/include/bit#L439-L456 libc++ (clang)] | See possible implementations in [https://github.com/gcc-mirror/gcc/blob/62c25d7adb1a5664982449dda0e7f9ca63cf4735/libstdc%2B%2B-v3/include/std/bit#L217-L248 libstdc++ (gcc)] and [https://github.com/llvm-mirror/libcxx/blob/78d6a7767ed57b50122a161b91f59f19c9bd0d19/include/bit#L439-L456 libc++ (clang)] | ||
− | + | {{eq fun|1= | |
+ | template <std::unsigned_integral T> | ||
+ | requires !std::same_as<T, bool> && !std::same_as<T, char> && | ||
+ | !std::same_as<T, char8_t> && !std::same_as<T, char16_t> && | ||
+ | !std::same_as<T, char32_t> && !std::same_as<T, wchar_t> | ||
+ | constexpr T bit_ceil(T x) noexcept | ||
+ | { | ||
+ | if (x <= 1u) | ||
+ | return T(1); | ||
+ | if constexpr (sizeof(+x) == sizeof(x)) | ||
+ | return T(1) << std::bit_width(T(x - 1)); | ||
+ | else { // for types subject to integral promotion | ||
+ | constexpr int offset_for_ub = | ||
+ | std::numeric_limits<unsigned>::digit - std::numeric_limits<T>::digit; | ||
+ | return T(1u << (std::bit_width(T(x - 1)) + offset_for_ub) >> offset_for_ub); | ||
+ | } | ||
+ | } | ||
+ | }} | ||
=== Example === | === Example === |
Revision as of 02:51, 11 April 2020
Defined in header <bit>
|
||
template< class T > constexpr T bit_ceil(T x); |
(since C++20) | |
Calculates the smallest integral power of two that is not smaller than x
. If that value is not representable in T
, the behavior is undefined.
This function is constexpr only if the result is representable in T
.
This overload participates in overload resolution only if T
is an unsigned integer type (that is, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, or an extended unsigned integer type).
Contents |
Parameters
x | - | values of unsigned integer type |
Return value
The smallest integral power of two that is not smaller than x
.
Exceptions
(none)
Possible implementation
See possible implementations in libstdc++ (gcc) and libc++ (clang)
template <std::unsigned_integral T> requires !std::same_as<T, bool> && !std::same_as<T, char> && !std::same_as<T, char8_t> && !std::same_as<T, char16_t> && !std::same_as<T, char32_t> && !std::same_as<T, wchar_t> constexpr T bit_ceil(T x) noexcept { if (x <= 1u) return T(1); if constexpr (sizeof(+x) == sizeof(x)) return T(1) << std::bit_width(T(x - 1)); else { // for types subject to integral promotion constexpr int offset_for_ub = std::numeric_limits<unsigned>::digit - std::numeric_limits<T>::digit; return T(1u << (std::bit_width(T(x - 1)) + offset_for_ub) >> offset_for_ub); } } |
Example
Run this code
#include <bit> #include <bitset> #include <iostream> auto main() -> int { using bin = std::bitset<8>; for (unsigned x{0}; x != 10; ++x) { auto const z = std::bit_ceil(x); // `ceil2` before P1956R1 std::cout << "bit_ceil(" << bin(x) << ") = " << bin(z) << '\n'; } }
Output:
bit_ceil(00000000) = 00000001 bit_ceil(00000001) = 00000001 bit_ceil(00000010) = 00000010 bit_ceil(00000011) = 00000100 bit_ceil(00000100) = 00000100 bit_ceil(00000101) = 00001000 bit_ceil(00000110) = 00001000 bit_ceil(00000111) = 00001000 bit_ceil(00001000) = 00001000 bit_ceil(00001001) = 00010000
See also
(C++20) |
finds the largest integral power of two not greater than the given value (function template) |