ビットごとの演算子の低レベルの使用例は、基数 2 の計算を実行することです。数値が 2 のべき乗であるかどうかをテストするためのよく知られたトリックがあります。
if ((x & (x - 1)) == 0) {
printf("%d is a power of 2\n", x);
}
ただし、より高いレベルの機能であるセット操作も提供できます。ビットの集まりをセットと考えることができます。説明するために、1 バイトの各ビットが 8 つの異なる項目を表すようにしましょう。たとえば、太陽系の惑星を考えてみましょう (冥王星はもはや惑星とは見なされないため、8 ビットで十分です!)。
#define Mercury (1 << 0)
#define Venus (1 << 1)
#define Earth (1 << 2)
#define Mars (1 << 3)
#define Jupiter (1 << 4)
#define Saturn (1 << 5)
#define Uranus (1 << 6)
#define Neptune (1 << 7)
次に、次のように惑星のコレクション (サブセット) を形成できます|
。
unsigned char Giants = (Jupiter|Saturn|Uranus|Neptune);
unsigned char Visited = (Venus|Earth|Mars);
unsigned char BeyondTheBelt = (Jupiter|Saturn|Uranus|Neptune);
unsigned char All = (Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune);
&
これで、 a を使用して、2 つのセットに交差があるかどうかをテストできます。
if (Visited & Giants) {
puts("we might be giants");
}
この^
演算は、2 つのセット (セットの和集合から交差を差し引いたもの) の違いを確認するためによく使用されます。
if (Giants ^ BeyondTheBelt) {
puts("there are non-giants out there");
}
したがって、|
ユニオン、&
交差点、^
ユニオンから交差点を差し引いたものと考えてください。
セットを表現するビットのアイデアを受け入れると、それらのセットを操作するのに役立つビット単位の演算が自然に存在します。