<bit>
関数
<bit>
ヘッダーには、次の非メンバー テンプレート関数が含まれます。
非メンバー関数 | 説明 |
---|---|
bit_cast |
オブジェクト表現を 1 つの型から別の型に再解釈します。 |
bit_ceil |
値以上の 2 の最小累乗を求めます。 |
bit_floor |
ある値を超えない 2 の最大のべき乗を求めます。 |
bit_width |
値を表すために必要な最小ビット数を求めます。 |
countl_zero |
最上位ビットから始めて、0 に設定された連続ビットの数をカウントします。 |
countl_one |
最上位ビットから始めて、1 に設定された連続ビットの数をカウントします。 |
countr_zero |
最下位ビットから始めて、0 に設定された連続ビットの数をカウントします。 |
countr_one |
最下位ビットから始めて、1 に設定された連続ビットの数をカウントします。 |
has_single_bit |
値に 1 に設定されたビットが 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
変換する値。
戻り値
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
解説
低レベルのコードでは、多くの場合、ある型のオブジェクトを別の型として解釈する必要があります。 再解釈されたオブジェクトのビット表現は元のオブジェクトと同じですが、型は異なります。
reinterpret_cast
または memcpy()
を使用する代わりに、これらの変換を行うには bit_cast()
が優れた方法です。 これは、次の理由で優れた方法です。
bit_cast()
はconstexpr
ですbit_cast()
では、型が普通にコピー可能であり、同じサイズである必要があります。 これにより、reinterpret_cast
とmemcpy
を使用して発生する可能性がある潜在的な問題を回避できます。これは、これらが誤って不適切に non-trivially-copyable 型への変換に使用される可能性があるためです。 また、memcpy()
を使用して、サイズが同じではない型間で誤ってコピーされる可能性があります。 たとえば、double (8 バイト) を符号なし int (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) を指定すると、値 5 を表す 3 つのバイナリ ビットが必要なので、3 が返されます。
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
テストする符号なし整数値。
戻り値
最も重要なビットから始まる、連続するビットの数を 1 に設定します。
例
#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
テストする符号なし整数値。
戻り値
最下位ビットから始まる連続するゼロビットの数。
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
値にビットセットが 1 つだけ含まれているかどうかを確認します。これは、値が 2 のべき乗であるかどうかをテストすることと同じです。
template <class T>
[[nodiscard]] constexpr bool has_single_bit(T value) noexcept;
パラメーター
value
テストする符号なし整数値。
戻り値
value
のビットセットが 1 つだけの場合は 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
以降が必要です。