ビット演算の真理値表を理解する
各論理ビット演算は、対応するビット位置のすべての組に独立して適用される、固定の真理値表に従います。
| ビットA | ビットB | AND | OR | XOR |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 |
- この計算機は入力を符号付き32ビット整数の範囲(0から2,147,483,647)に制限しています。これは、ECMAScript仕様に従い、JavaScriptのビット演算子が内部的に数値を演算前に32ビット表現に変換するためです。
- NOT(~A)は常に、符号付き32ビット整数として解釈すると−(A + 1)に等しい結果を生成します——この計算機は表示される2進数表記があいまいにならないよう、符号なし32ビット相当の値を表示します(たとえば~12は−13ではなく4,294,967,283と表示されます)。
- 31より大きいシフト量(B)は、この計算機では31に制限されます。JavaScriptでは32ビット値を32以上の位置でシフトすると、直感的に期待されるような0にはならず、ラップアラウンドが発生する(シフト量の下位5ビットのみが使われる)ためです。
ビット演算とは?
ビット演算は、通常の10進数の算術を行うのではなく、数を個々の2進数の桁(ビット)のレベルで処理し、その2進表記の0と1を比較したりシフトしたりします。すべての整数は、それぞれ2の累乗を表すビットの並びとして2進数で書くことができます——たとえば12を2進数で表すと1100であり、これは1×8 + 1×4 + 0×2 + 0×1を意味します。
論理ビット演算——AND、OR、XOR(排他的論理和)、NOT——は、標準的なブール論理の規則に従って、2つの数の対応するビット位置を比較する(あるいは1つの数のビットを反転させる)操作であり、各ビット位置に独立して適用されます。シフト演算——左シフトと右シフト——は、数のすべてのビットを指定した位置数だけ左または右に移動させるもので、数学的には2の累乗による乗算または除算と同等です。
ビット演算はコンピューターサイエンスと低水準プログラミングの基礎です。一連のオプションの中の個々のフラグを設定・消去・確認すること(ビットフラグ)、2の累乗による高速な乗算・除算、暗号アルゴリズム、グラフィックスと色の操作(赤・緑・青の各チャンネルの合成)、コンパクトなデータ符号化などに使われます。
このビット演算計算機の使い方
- 1つ目の数(A)を0以上の整数として入力します(符号付き32ビット整数の範囲である0から2,147,483,647まで)。
- 2つ目の数(B)を入力します。AND、OR、XORの場合、これはAとビットごとに比較される2つ目のオペランドです。シフト演算の場合、これはシフトする位置数です(0〜31が有効であり、それより大きい値は31に制限されます)。NOTの場合、NOTはAのみに作用するため、Bは無視されます。
- 演算を選択します。AND、OR、XOR、NOT、左シフト、右シフトのいずれかです。
- 10進数の結果と、A、B(またはシフト量)、結果の2進数表記を確認します。
各ビット演算の仕組み
ANDは各ビット位置を比較し、両方のビットが1である位置でのみ1を返し、それ以外は0を返します。計算例:12(1100)AND 10(1010)= 8(1000)。これは両方の数で1になっているのは3番目のビット位置(値8)だけだからです。
ORは各ビット位置を比較し、2つのビットのうち少なくとも一方が1であれば1を返します。計算例:12(1100)OR 10(1010)= 14(1110)。XOR(排他的論理和)は、2つのビットのうちちょうど一方だけが1である場合(両方ではなく)に1を返します。計算例:12(1100)XOR 10(1010)= 6(0110)。
NOTは1つの数のすべてのビットを反転させます(0は1に、1は0になります)。この計算機は32ビット値を扱うため、NOT 12はすべての32ビットを反転させ、符号なし32ビット整数として解釈すると4,294,967,283になります(符号付き整数として解釈した場合の−13の2の補数表現です)。
左シフト(A << B)はAのすべてのビットをB位置だけ左に移動させ、空いた下位ビットを0で埋めます——これはAを2^B倍することと同等です。計算例:12 << 2 = 48(12 × 2² = 12 × 4 = 48と同等)。右シフト(A >> B)はAのすべてのビットをB位置だけ右に移動させ、下位ビットを切り捨てます——これはAを2^Bで整数除算し、切り捨てることと同等です。計算例:12 >> 2 = 3(⌊12 ÷ 4⌋ = 3と同等)。
よくある間違い
- ビットごとのAND/ORと論理(ブール)AND/ORを混同する——ビット演算子は数のすべてのビットに独立して作用しますが、論理演算子は値全体を単一の真偽条件として扱います。この2つは、値が0と1である特殊な場合を除き、異なる結果を生みます。
- 大きな量だけ左シフトすると、常に比例して大きな数になると期待する——十分に大きくシフトすると、有効なビットが32ビットの境界を超えて押し出され、切り捨てられる(オーバーフローする)ことがあります。
- NOTの結果を読み違える——NOTは32ビットすべてを反転させるため、~Aの符号なし10進数の結果はA自身よりもずっと大きく見えますが、符号付き2の補数として解釈すると、実際には小さな負の数、−(A+1)を表しています。
- 右シフトを常に通常の除算と同等だと考える——非負整数における右シフトは、2の累乗による整数の切り捨て除算と正確に一致しますが、負の数に対する挙動は、算術シフトと論理シフトのどちらが使われるかによって異なります。
よくある質問
ビットごとのANDと論理ANDの違いは何ですか?
ビットごとのAND(&)は2つの数をビットごとに比較し、対応する両方の入力ビットが1の場合にのみ各ビットが1になる新しい数を返します——たとえば12 & 10 = 8です。論理AND(&&)は値全体をそれぞれ単一の真偽条件として扱い、個々のビットを組み合わせるのではなく真偽性を評価して、元のオペランドのいずれか、またはブール値を返します。この2つの演算子は目的が異なり、一般にまったく異なる結果を生みます。
XORはどのように動作しますか?
XOR(排他的論理和)は2つの数をビットごとに比較し、対応する2つのビットのうちちょうど一方だけが1である(両方でも、どちらでもないでもない)位置に1を返します。12(1100)XOR 10(1010)の場合:各ビット位置を比較すると0110となり、10進数では6です。XORはビットの反転、2つの値の差の検出、単純なチェックサムやパリティの計算によく使われます。
左シフトは何をしますか?
左シフト(A << B)は、Aの2進数表記のすべてのビットをB位置だけ左に移動させ、新しく空いた下位の位置を0で埋めます。これは数学的にはAを2のB乗倍することと同等です。たとえば12 << 2 = 48であり、これは12 × 2² = 12 × 4 = 48と同じ結果です。
ビットごとのNOTは何をしますか?
ビットごとのNOT(~A)はAのすべてのビットを反転させます——すべての0は1になり、すべての1は0になります。12の32ビット表現(00000000000000000000000000001100)に適用すると、NOTはそれらすべてのビットを反転させた値を生成し、符号なし32ビット数としては4,294,967,283と表示され、符号付き整数としては2の補数形式で−13を表します(~A = −(A+1)という恒等式に従います)。
右シフトは除算とどう違いますか?
非負整数の場合、右シフト(A >> B)は2^Bによる整数の切り捨て除算とまったく同じ結果を生みます:A >> B = ⌊A ÷ 2^B⌋。たとえば12 >> 2 = 3であり、⌊12 ÷ 4⌋ = 3と一致します。この2つの演算は負の数では異なる結果になることがあり、その場合、シフトの種類(算術シフトか論理シフトか)が符号ビットの扱いにどう影響するかが関係します——これは、より低水準のプログラミングの文脈で重要になる詳細です。
なぜここではビット演算が32ビット整数に限定されているのですか?
JavaScriptの組み込みビット演算子(&, |, ^, ~, <<, >>)は、ECMAScript言語仕様に従い、演算を実行する前に内部的にオペランドを32ビット整数に変換します。この計算機はその標準的な挙動を反映しているため、入力は32ビットで表現できる範囲(ここで受け付けている0以上の値については0から2,147,483,647まで)に制限されています。
参考文献
- Warren HS Jr. Hacker's Delight. 2nd ed. Addison-Wesley, 2012. (Standard reference for bitwise algorithms and two's-complement arithmetic.)
- ECMA International. ECMA-262: ECMAScript Language Specification, §6.1.6.1 (Bitwise operators, ToInt32/ToUint32). ecma-international.org.
- Patterson DA, Hennessy JL. Computer Organization and Design: The Hardware/Software Interface. 5th ed. Morgan Kaufmann, 2013. (Binary representation and bitwise logic.)