C++ベース-シンプルで強力なbitset
いくつかの簡単な原子操作は、複雑で強力な機能を組み合わせることが多い.ビット操作の深い意味は,数値を表すことではなく,可能なケース数である.ビットセットがどのように複雑な機能を組み合わせているのかはしばらく分かりませんが、冥冥の中でこのような直感的な感じがします.
basis
<bitset>
#include <bitset>
std::bitset<8> bs;
// size_t (value),
// numeric_limits<size_t>::min() == 0
// std::bitset<8> 8 ,
// 0
cout << bs.to_ulong() << endl; // 0
cout << bs.to_string() << endl; // 00000000
bitsetの構造
唯一注意しなければならないのは、bitset<>テンプレートクラスは中括弧演算子を再ロードしているが、bs[0]は、この数値を先頭ではなくバイナリに変換するときの最後尾要素を表す(その意味と配列は異なる).
std::bitset<8> bs;
//bs[0] = 1; // 0000 0001
//bs[7] = 1; // 1000 0000
std::bitset<8> bs(7);
bs.to_string() // 0000 0111
std::bitset<8> bs(0x07);
bs.to_string() // 0000 0111
ここにもいくつかの大きな構造があります.
bitset<numeric_limits<unsigned short>::digits> bs1(267);
// 16
bitset<numeric_limits<unsigned long>::digits> bs2(267);
// 32
std::bitset<8> bs("00000111");
bs.to_ulong(); // 7
bitsetの操作
メンバー関数
関数の機能
bs.any()
値が1のバイナリビットが存在するかどうか
bs.none()
値が1のバイナリビットが存在しないか、または全部位が0であるか
bs.size()
ビット長、すなわち非テンプレートパラメータ値
bs.count()
値が1の個数
bs.test(pos)
posのバイナリビットが1と0であるかどうかをテストします.
bs.set()
すべての位置1
bs.set(pos)
posビットにおけるバイナリ位置1と1の演算または演算
bs.reset()
すべての位置0
bs.reset(pos)
posビットにおけるバイナリ位置0と0の演算
bs.flip()
すべてのビットを逆にする
bs.flip(pos)
posでのバイナリビット反転
bs.to_ulong()
バイナリをunsigned long出力に変換
bs.to_string()
バイナリを文字列出力に変換
~bs
ビット別逆効果はbsと等価である.flip()
os << b
バイナリビットをosストリームの小さい値を右に出力し、大きい値を左に出力します.
いくつかの高度な使い方
まず、簡単な例を見てみましょう.
"1000 0000" - > 1
"1000 1000" - > 17
2進数から10進数への変換をどのように実現するか、そして2進数の表現形式は逆順序の形式であり、すなわち低位が前である.
int bin2dec(const string& bin)
{
std::bitset<8> bs(string(bin.rbegin(), bin.rend()));
return bs.to_ulong();
}
ここで冒頭引用を振り返ると、bitsetの強みは、1つのバイナリの数値ではなく、1つのケース数を表し、1つのバイナリビットは2つのケースを表し、2つのバイナリビットは4つの状況数を表し、3つのバイナリビットは8つの状況数を表すなどである.
Bitsetsをフラグのセットと見なす
enum Color{red, yellow, green, blue, white, black, numColors};
// ,
bitset<numColors> usedColors;
// something happens
usedColors.set(red);
usedColors.set(blue);
cout << "bitfield of used colors: " << usedColors << endl;
cout << "bitfield of unused colors: " << ~usedColors << endl;
// process if any color is used
if (usedColors.any())
{
for (int c = 0; c < numColors; ++c)
{ // , 1
if (usedColor[Color(c)])
{
//
}
}
}