ビット演算>論理和

まずは、前回の演習問題の解答から。

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

解答例は「i & 0xff」だ。
C++14から使用できる2進数表記を使えば「i & 0b11111111」とも書ける。

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

解答例は「i & 0xffffff00」だ。
後で説明するビット反転を使えば、「i & ~0xff」または「i & ~0b11111111」(C++14)とも書けるぞ。


さて、論理和の話を始めよう。
論理和とは or のことだ。C/C++ の式では、二項演算子として 「|」 記号を使用する。

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

A B A | B
0 0 0
0 1 1
1 0 1
1 1 1

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

論理和の場合、入力が両方0の時のみ結果が0で、それ以外(どちらから一方が1、または 両方が1)の場合の結果は1になる。
桁上りがある場合を除けば入力の加算と同じなので論理和と呼ばれる。

重要な視点は、

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

ということである。

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

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

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

X | 1 = 1 | X = 1
X | 0 = 0 | X = X

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

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

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

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

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

これを業界用語で、2番めの値の ビットを立てる と呼ぶ。
(※ フラグビットを立てる とも言う)

つまり、論理和により、ビット列の指定箇所だけを強制的に1にすることが出来るということだ。

演習問題:

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