ビット演算>論理積

まずは論理積から解説しよう。

論理積とは and のことだ。C/C++ の式では、二項演算子として 「&」 記号を使用する。

1ビットの場合、論理積演算結果は以下のようになる。

A B A & B
0 0 0
0 1 0
1 0 0
1 1 1

A, B が入力で、A & B のカラムが演算結果だ。

論理積の場合、入力が両方1の時のみ結果が1で、それ以外(どちらから一方が0、または 両方が0)の場合の結果は0になる。
入力の乗算と同じなので論理積と呼ばれる。

重要な視点は、

  • Aが0の場合は、Bが何であっても、結果は0になる。
  • Aが1の場合は、Bの値がそのまま結果になる。

ということである。

「A & B」 と 「B & A」 の結果は同じ値だ。交換則が成立している。
なので、以下のようにも言える。

  • Bが0の場合は、Aが何であっても、結果は0になる。
  • Bが1の場合は、Aの値がそのまま結果になる。

上記を数式で書くと以下のようになる。

X & 1 = 1 & X = X
X & 0 = 0 & X = 0

これまでの説明は1ビットのみであったが、ビットがたくさんある場合はどうなのであろうか?

C/C++ では 変数と整数の論理積がよく使用される。変数が int 型の場合32ビットとかで、1ビットではなく多ビットだ。
で、「多ビットの値どうしの論理積は、各ビットごとに計算される。」ということだ。

例えば、0b10101010 と 0b00001111 との論理積をとると、0b00001010 となる。
※ 0b は2進数を表す前置記号で、C++14 から使用できる。

0b10101010
0b00001111
———-
0b00001010

ここで先ほどの視点を思い出して欲しい。

入力の2番めは上位4ビットが0で、下位4ビットが1だ。0と論理積を取ると1番目の値に関係なく結果は0,1と論理積をとると、1番目の値がそのまま結果にあらわれているのが分かるだろうか?

これを業界用語で、2番めの値で マスクを取る と呼ぶ。
つまり、論理積により、ビット列の必要な箇所だけを取り出すことが出来るということだ。

別の見方をすると、上記は4~7ビット目を強制的に0にしている、とも見れる。
これを業界用語でフラグを落とすと呼ぶ。
つまり、論理積により、ビット列の必要な箇所を強制的に0にすることが出来るということだ。

演習問題:

  1. int x; になんらかの値が入っている時、下位8ビットのみを取り出すコードを書きなさい
  2. int x; になんらかの値が入っている時、下位8ビットを強制的に0にするコードを書きなさい

解答例は こちら