AND・OR・XOR・NOTなど、ビット単位で行う論理演算。フラグ管理やマスク処理でプログラミングに必須の技術です。
ビット演算は、2進数の各桁(ビット)ごとに論理演算を行う操作です。 通常の足し算や掛け算が「数値全体」を対象にするのに対し、ビット演算は1ビット単位で独立に処理します。 デジタル回路の最も基本的な動作であり、CPUの内部はビット演算の組み合わせでできています。
プログラミングでは、フラグ管理・マスク処理・暗号化・画像処理・ネットワークのサブネット計算など、幅広い場面で使われます。 たとえば「8つのON/OFFスイッチの状態を1バイト(8ビット)にまとめて管理する」といった用途は、ビット演算の典型例です。
ビット演算の中でもAND・OR・XOR・NOTの4つが基本となります。 上のツールで2つの値を入力すると、各ビット位置でどのように演算されるかをリアルタイムで確認できます。
AND演算は、対応するビットが両方とも1のときだけ結果が1になります。 どちらか一方でも0なら結果は0です。日常で例えるなら「AさんもBさんも賛成したときだけ可決」というイメージです。
8ビットの具体例を見てみましょう。A=11010110(10進で214)と B=00001111(10進で15)をANDすると、 結果は00000110(10進で6)です。Bが1の位置だけAの値が残り、Bが0の位置はすべて0になります。
このように特定のビットだけを取り出す操作をマスク処理と呼びます。 上のツールでA=214、B=15を入力し、AND演算で下位4ビットだけが取り出される様子を確認してみてください。
OR演算は、対応するビットのどちらか一方でも1なら結果が1になります。 両方0のときだけ結果が0です。日常で例えるなら「AさんかBさんのどちらかが賛成すれば可決」というイメージです。
8ビットの具体例です。A=10100000(10進で160)と B=00000101(10進で5)をORすると、 結果は10100101(10進で165)です。Bが1の位置が強制的に1になり、他のビットはAの値がそのまま残ります。
このように特定のビットを確実に1にする操作をビットセットと呼びます。 フラグを立てる(有効にする)処理で多用されます。上のツールで実際に値を入力して確認してみてください。
XOR(排他的論理和)は、対応するビットが異なるときだけ結果が1になります。 同じ値どうし(0と0、1と1)なら結果は0です。「どちらか一方だけが1」のときに1になるので「排他的」と呼ばれます。
XORの最も重要な性質は、同じ値でもう一度XORすると元に戻ることです。 たとえば A XOR B = C としたとき、C XOR B = A になります。 この性質を利用して、簡単な暗号化ができます(平文 XOR 鍵 = 暗号文、暗号文 XOR 鍵 = 平文)。
また、反転させたいビット位置に1を立てた値とXORを取ると、そのビットだけがトグル(反転)されます。 LEDの点滅制御やチェックサム計算にも使われる、非常に便利な演算です。 上のツールでA=B(同じ値)を入力すると結果が0になることを確認してみてください。
NOT演算は、すべてのビットを反転します。1は0に、0は1になります。 AND・OR・XORが2つの入力を取るのに対し、NOTは入力が1つだけの単項演算です。
8ビットの具体例を見てみましょう。10110011(10進で179)をNOTすると、01001100(10進で76)になります。 179 + 76 = 255(= 11111111)であることに注目してください。NOTの結果と元の値を足すと全ビットが1になります。
NOTの結果は1の補数とも呼ばれます。 ここにさらに1を足すと2の補数(= 符号反転した値)が得られます。 2の補数はコンピュータが負の数を表現する基本的な方法です。 上のツールで「NOT」を選び、値を変えて反転の様子を確認してみてください。
マスク処理とは、特定のビット位置だけを操作するテクニックです。 操作したいビット位置に1を立てた「マスク値」を用意し、目的に応じた演算を使います。 実用例として、色の値からRGBを取り出す処理があります。24ビットカラー値 0xFFAA33 から赤成分(0xFF)を得るには、0xFF0000 とANDして右に16ビットシフトします。
4つの基本パターンを覚えましょう。
・取り出し(AND): マスクが1の位置だけ残り、他は0になる。
・セット(OR): マスクが1の位置を強制的に1にする。
・クリア(AND NOT): マスクが1の位置を強制的に0にする。
・トグル(XOR): マスクが1の位置のビットを反転する。
たとえばゲームで「毒・麻痺・睡眠」などの状態異常を8ビットのフラグで管理するなら、 「毒を付与」は OR 00000001、「毒かどうか判定」は AND 00000001、「毒を解除」は AND NOT 00000001 です。 上のツールの「フラグ管理」モードに切り替えると、これらの操作を実際に試せます。
シフト演算とは、ビット列全体を左または右に決まった桁数だけ「ずらす」操作です。
・左シフト(<< n):全ビットをn桁左へ。空いた右端に0が入る。値が2のn乗倍になる
・右シフト(>> n):全ビットをn桁右へ。空いた左端に0(符号なし)が入る。値が2のn乗で割った商になる
なぜシフトで掛け算・割り算になるのか。2進数の桁は右から「1・2・4・8・16…」と2倍ずつ増えています。ビットを1桁左にずらすと、元の「1の位」が「2の位」へ、「2の位」が「4の位」へ移動します。桁の重みが2倍になるため、値全体が2倍になるのです。
具体例:5(00000101) を左に1ずらすと 10(00001010)、右に1ずらすと 2(00000010)。コンピュータにとって乗除算より速いため、速度が重要な処理では掛け算・割り算の代わりにシフトがよく使われます。
コンピュータが扱えるのは、電流が「ある(1)」か「ない(0)」かの2状態だけです。CPUの中にはトランジスタ(=電気スイッチ)が数十億個並んでおり、1つのスイッチが1ビットを表します。
なぜAND・OR・NOTだけで"なんでも計算できる"のか。実は、足し算・引き算・掛け算、さらには条件分岐まで、すべてAND/OR/NOTの組み合わせで表せることが数学的に証明されています(論理ゲートの理論)。つまりビット演算はコンピュータの計算能力全体の土台です。
日常のプログラミングでも使う場面は身近です。
・フラグ管理:ゲームのアイテム所持フラグ、権限フラグなどを1バイトにまとめる
・画像処理:ピクセルの色(R/G/B各8ビット)を取り出す・加工する
・ネットワーク:IPアドレスとサブネットマスクのAND演算でネットワーク部を求める
それぞれの場面で「AND・OR・XOR・シフト」のどれが合うかを考える力が、ビット演算学習の核心です。
| 対象 | rwx表記 | 2進数 | 8進数 | 意味 |
|---|---|---|---|---|
| 所有者 | rwx | 111 | 7 | 読取+書込+実行 |
| グループ | r-x | 101 | 5 | 読取+実行 |
| その他 | r-x | 101 | 5 | 読取+実行 |
UNIXのファイルパーミッションchmod 755は、ビット演算の実用例として最もよく知られています。読取(r)=4、書込(w)=2、実行(x)=1 の3つのフラグをOR演算で組み合わせて表します。 7 = 4+2+1 = rwx(読取+書込+実行)、5 = 4+0+1 = r-x(読取+実行)です。
「そのユーザーに実行権限があるか?」を調べるにはflags AND 001を計算します。 結果が0以外なら実行可能です。これがまさにANDによるマスク処理(ビット判定)です。 書込権限を追加するならflags OR 010、書込権限を取り消すならflags AND NOT 010です。
このようにビット演算は「1つの数値に複数のフラグを詰め込み、個別に操作する」という使い方の基本です。 パーミッションに限らず「ビットフラグの判定・設定・クリア」は、AND/OR/NOT の組み合わせで実現できます。