<bit>
函数
<bit>
标头包括以下非成员模板函数:
非成员函数 | 描述 |
---|---|
bit_cast |
将对象表示形式从一种类型重新解释为另一种类型。 |
bit_ceil |
求大于或等于某个值的 2 的最小幂。 |
bit_floor |
求不大于某个值的 2 的最大幂。 |
bit_width |
求表示某个值所需的最小位数。 |
countl_zero |
从最高有效位开始对设置为 0 的连续位数进行计数。 |
countl_one |
从最高有效位开始对设置为 1 的连续位数进行计数。 |
countr_zero |
从最低有效位开始对设置为 0 的连续位数进行计数。 |
countr_one |
从最低有效位开始对设置为 1 的连续位数进行计数。 |
has_single_bit |
检查某个值是否仅将一个位设置为 1。 这与测试某个值是否为 2 的幂相同。 |
popcount |
对设置为 1 的位数进行计数。 |
rotl |
计算按位左旋转的结果。 |
rotr |
计算按位右旋转的结果。 |
bit_cast
将 From
类型的对象中的位模式复制到 To
类型的新对象。
template <class To, class From>
[[nodiscard]] constexpr To bit_cast(const From& from) noexcept;
参数
操作
输出的类型。
From
要转换的值的类型。
from
要转换的值。
返回值
一个 To
类型的对象。
结果中的每个位都与 from
中的相应位匹配,除非 To
中有填充位,在这种情况下,结果中的这些位未指定。
示例
#include <bit>
#include <iostream>
int main()
{
float f = std::numeric_limits<float>::infinity();
int i = std::bit_cast<int>(f);
std::cout << "float f = " << std::hex << f
<< "\nstd::bit_cast<int>(f) = " << std::hex << i << '\n';
return 0;
}
float f = inf
std::bit_cast<int>(f) = 7f800000
备注
低级别代码通常需要将一种类型的对象解释为另一种类型。 重新解释的对象与原始对象具有相同的位表示形式,但类型不同。
bit_cast()
是进行这些转换的更好方法,而不是使用 reinterpret_cast
或 memcpy()
。 这种方法更好是因为:
bit_cast()
是constexpr
bit_cast()
要求类型易于复制且大小相同。 这可以防止使用reinterpret_cast
和memcpy
时可能会遇到的潜在问题,因为它们可能会用于无意中错误地转换不可复制的类型。 此外,memcpy()
还可用于无意中复制不同大小的类型。 例如,将双精度(8 字节)转换为无符号整数(4 字节),或者反过来。
仅当符合以下条件时,此重载才参与重载解析:
sizeof(To) == sizeof(From)
To
和From
为 is_trivially_copyable。
当且仅当 To
、From
及其子对象的类型符合以下条件时,此函数模板为 constexpr
:
- 不是联合类型或指针类型
- 不是指向成员类型的指针
- 不是 volatile 限定
- 没有作为引用类型的非静态数据成员
bit_ceil
求大于或等于某个值的 2 的最小幂。 例如,给定 3
,则返回 4
。
template<class T>
[[nodiscard]] constexpr T bit_ceil(T value);
参数
value
要测试的无符号整数值。
返回值
求大于或等于 value
的 2 的最小幂。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
for (auto i = 0u; i < 6u; ++i) // bit_ceil() takes an unsigned integer type
{
auto nextClosestPowerOf2 = std::bit_ceil(i);
std::cout << "\nbit_ceil(0b" << std::bitset<4>(i) << ") = "
<< "0b" << std::bitset<4>(nextClosestPowerOf2);
}
return 0;
}
bit_ceil(0b0000) = 0b0001
bit_ceil(0b0001) = 0b0001
bit_ceil(0b0010) = 0b0010
bit_ceil(0b0011) = 0b0100
bit_ceil(0b0100) = 0b0100
bit_ceil(0b0101) = 0b1000
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
bit_floor
求不大于某个值的 2 的最大幂。 例如,给定 5
,则返回 4
。
template< class T >
[[nodiscard]] constexpr T bit_floor(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
不大于 value
的 2 的最大幂。
如果 value
为 0,则返回 0。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
for (auto i = 0u; i < 6u; ++i) // bit_floor() takes an unsigned integer type
{
auto previousPowerOf2 = std::bit_floor(i);
std::cout << "\nbit_floor(0b" << std::bitset<4>(i) << ") = 0b"
<< std::bitset<4>(previousPowerOf2);
}
return 0;
}
bit_floor(0b0000) = 0b0000
bit_floor(0b0001) = 0b0001
bit_floor(0b0010) = 0b0010
bit_floor(0b0011) = 0b0010
bit_floor(0b0100) = 0b0100
bit_floor(0b0101) = 0b0100
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
bit_width
求表示某个值所需的最小位数。
例如,给定 5 (0b101),则返回 3,因为它需要 3 个二进制位来表示值 5。
template<class T>
[[nodiscard]] constexpr T bit_width(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
表示 value
所需的位数。
如果 value
为 0,则返回 0。
示例
#include <bit>
#include <iostream>
int main()
{
for (unsigned i=0u; i <= 8u; ++i)
{
std::cout << "\nbit_width(" << i << ") = "
<< std::bit_width(i);
}
return 0;
}
bit_width(0) = 0
bit_width(1) = 1
bit_width(2) = 2
bit_width(3) = 2
bit_width(4) = 3
bit_width(5) = 3
bit_width(6) = 3
bit_width(7) = 3
bit_width(8) = 4
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
countl_zero
从最高有效位开始对设置为 0 的连续位数进行计数。
template<class T>
[[nodiscard]] constexpr int countl_zero(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
从最高有效位开始的连续 0 位数。
如果 value
为 0,则返回类型 value
中的位数。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
for (unsigned char result = 0, i = 0; i < 9; i++)
{
std::cout << "\ncountl_zero(0b" << std::bitset<8>(result) << ") = " << std::countl_zero(result);
result = result == 0 ? 1 : result * 2;
}
return 0;
}
countl_zero(0b00000000) = 8
countl_zero(0b00000001) = 7
countl_zero(0b00000010) = 6
countl_zero(0b00000100) = 5
countl_zero(0b00001000) = 4
countl_zero(0b00010000) = 3
countl_zero(0b00100000) = 2
countl_zero(0b01000000) = 1
countl_zero(0b10000000) = 0
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
countl_one
从最高有效位开始对设置为 1 的连续位数进行计数。
template<class T>
[[nodiscard]] constexpr int countl_one(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
从最有效位开始的设置为一的连续位数。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
unsigned char value = 0;
for (unsigned char bit = 128; bit > 0; bit /= 2)
{
value |= bit;
std::cout << "\ncountl_one(0b" << std::bitset<8>(value) << ") = "
<< std::countl_one(value);
}
return 0;
}
countl_one(0b10000000) = 1
countl_one(0b11000000) = 2
countl_one(0b11100000) = 3
countl_one(0b11110000) = 4
countl_one(0b11111000) = 5
countl_one(0b11111100) = 6
countl_one(0b11111110) = 7
countl_one(0b11111111) = 8
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
countr_zero
从最低有效位开始对设置为 0 的连续位数进行计数。
template<class T>
[[nodiscard]] constexpr int countr_zero(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
从最低有效位开始的连续 0 位数。
如果 value
为 0,则返回类型 value
中的位数。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
for (unsigned char result = 0, i = 0; i < 9; i++)
{
std::cout << "\ncountr_zero(0b" << std::bitset<8>(result) << ") = "
<< std::countr_zero(result);
result = result == 0 ? 1 : result * 2;
}
return 0;
}
countr_zero(0b00000000) = 8
countr_zero(0b00000001) = 0
countr_zero(0b00000010) = 1
countr_zero(0b00000100) = 2
countr_zero(0b00001000) = 3
countr_zero(0b00010000) = 4
countr_zero(0b00100000) = 5
countr_zero(0b01000000) = 6
countr_zero(0b10000000) = 7
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
countr_one
从最低有效位开始对设置为 1 的连续位数进行计数。
template<class T>
[[nodiscard]] constexpr int countr_one(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
从最低有效位开始的设置为 1 的连续位数。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
unsigned char value = 0;
for (int bit = 1; bit <= 128; bit *= 2)
{
value |= bit;
std::cout << "\ncountr_one(0b" << std::bitset<8>(value) << ") = "
<< std::countr_one(value);
}
return 0;
}
countr_one(0b00000001) = 1
countr_one(0b00000011) = 2
countr_one(0b00000111) = 3
countr_one(0b00001111) = 4
countr_one(0b00011111) = 5
countr_one(0b00111111) = 6
countr_one(0b01111111) = 7
countr_one(0b11111111) = 8
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
has_single_bit
检查某个值是否只设置了一个位。这与测试某个值是否为 2 的幂相同。
template <class T>
[[nodiscard]] constexpr bool has_single_bit(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
如果 value
只设置了一个位,则为 true
,这也意味着 value
是 2 的幂。 否则为 false
。
示例
#include <bit>
#include <bitset>
#include <iostream>
#include <iomanip>
int main()
{
for (auto i = 0u; i < 10u; ++i)
{
std::cout << "has_single_bit(0b" << std::bitset<4>(i) << ") = "
<< std::boolalpha << std::has_single_bit(i) << '\n';
}
return 0;
}
has_single_bit(0b0000) = false
has_single_bit(0b0001) = true
has_single_bit(0b0010) = true
has_single_bit(0b0011) = false
has_single_bit(0b0100) = true
has_single_bit(0b0101) = false
has_single_bit(0b0110) = false
has_single_bit(0b0111) = false
has_single_bit(0b1000) = true
has_single_bit(0b1001) = false
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
popcount
对无符号整数值中设置为 1 的位数进行计数。
template<class T>
[[nodiscard]] constexpr int popcount(T value) noexcept;
参数
value
要测试的无符号整数值。
返回值
value
中设置为 1 的位数。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
for (unsigned char value = 0; value < 16; value++)
{
std::cout << "\npopcount(0b" << std::bitset<4>(value) << ") = "
<< std::popcount(value);
}
return 0;
}
popcount(0b0000) = 0
popcount(0b0001) = 1
popcount(0b0010) = 1
popcount(0b0011) = 2
popcount(0b0100) = 1
popcount(0b0101) = 2
popcount(0b0110) = 2
popcount(0b0111) = 3
popcount(0b1000) = 1
popcount(0b1001) = 2
popcount(0b1010) = 2
popcount(0b1011) = 3
popcount(0b1100) = 2
popcount(0b1101) = 3
popcount(0b1110) = 3
popcount(0b1111) = 4
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
rotl
将无符号整数值的位向左旋转指定的次数。 从最左侧的位“掉出”的位将旋转到最右侧的位。
template<class T>
[[nodiscard]] constexpr T rotl(T value, int s) noexcept;
参数
value
要旋转的无符号整数值。
s
要执行的左旋转数。
返回值
将 value
向左旋转 s
次的结果。
如果 s
为 0,则返回 value
。
如果 s
为负数,则执行 rotr(value, -s)
。 从最右侧的位“掉出”的位将旋转到最左侧的位。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
unsigned char bits = 1;
for (int i = 0; i < 8; ++i)
{
std::cout << "rotl(0b" << std::bitset<8>(bits) << ", 1) = ";
bits = std::rotl(bits, 1);
std::cout << "0b" << std::bitset<8>(bits) << '\n';
}
std::cout << "rotl(0b" << std::bitset<8>(bits) << ",-1) = ";
bits = std::rotl(bits, -1);
std::cout << "0b" << std::bitset<8>(bits);
return 0;
}
rotl(0b00000001, 1) = 0b00000010
rotl(0b00000010, 1) = 0b00000100
rotl(0b00000100, 1) = 0b00001000
rotl(0b00001000, 1) = 0b00010000
rotl(0b00010000, 1) = 0b00100000
rotl(0b00100000, 1) = 0b01000000
rotl(0b01000000, 1) = 0b10000000
rotl(0b10000000, 1) = 0b00000001
rotl(0b00000001,-1) = 0b10000000
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
rotr
将 value
的位向右旋转指定次数。 从最右侧的位“掉出”的位将旋转回最左侧的位。
template<class T>
[[nodiscard]] constexpr T rotr(T value, int s) noexcept;
参数
value
要旋转的无符号整数值。
s
要执行的右旋转数。
返回值
将 value
向右旋转 s
次的结果。
如果 s
为 0,则返回 value
。
如果 s
为负数,则执行 rotl(value, -s)
。 从最左侧的位“掉出”的位将旋转回最右侧的位。
示例
#include <bit>
#include <bitset>
#include <iostream>
int main()
{
unsigned char bits = 128;
for (int i = 0; i < 8; ++i)
{
std::cout << "rotr(0b" << std::bitset<8>(bits) << ", 1) = ";
bits = std::rotr(bits, 1);
std::cout << "0b" << std::bitset<8>(bits) << '\n';
}
std::cout << "rotr(0b" << std::bitset<8>(bits) << ",-1) = ";
bits = std::rotr(bits, -1);
std::cout << "0b" << std::bitset<8>(bits);
return 0;
}
rotr(0b10000000, 1) = 0b01000000
rotr(0b01000000, 1) = 0b00100000
rotr(0b00100000, 1) = 0b00010000
rotr(0b00010000, 1) = 0b00001000
rotr(0b00001000, 1) = 0b00000100
rotr(0b00000100, 1) = 0b00000010
rotr(0b00000010, 1) = 0b00000001
rotr(0b00000001, 1) = 0b10000000
rotr(0b10000000,-1) = 0b00000001
备注
仅当 T
为无符号整数类型时,此模板函数才参与重载解析。 例如:unsigned int
、unsigned long
、unsigned short
、unsigned char
等。
要求
标头:<bit>
命名空间: std
需要 /std:c++20
或更高版本。