2の補数表現
コンピュータが2の補数を使用して負の整数を表現する方法を学びます。NOT、加算、符号付き数値の関係を理解します。
Number Representation
詳細な説明
2の補数:コンピュータが負の数を格納する方法
2の補数は最新のコンピュータで符号付き整数を表現する普遍的な方法です。同じ加算回路が正と負の両方の数で動作することをエレガントに可能にします。
2の補数の計算方法
2の補数で数値を否定するには:
- すべてのビットを反転(ビットNOT)
- 1を加算
42 = 00101010
~42 = 11010101 (ステップ1: 全ビット反転)
+ 1 (ステップ2: 1を加算)
──────────
-42 = 11010110
検証
42 + (-42) はゼロになるはず:
00101010
+ 11010110
──────────
100000000 (9ビット — キャリーアウトは8ビットで破棄)
= 00000000 (正しい!)
値の範囲
Nビット2の補数整数の場合:
- 最小値:
-2^(N-1) - 最大値:
2^(N-1) - 1
| ビット幅 | 最小 | 最大 |
|---|---|---|
| 8ビット | -128 | 127 |
| 16ビット | -32768 | 32767 |
| 32ビット | -2^31 | 2^31-1 |
NOTのショートカット
2の補数の否定は~A + 1なので、以下の恒等式が成り立ちます:
~A = -(A + 1)
つまり~0 = -1、~1 = -2、~(-1) = 0です。
なぜ2の補数か?
- ゼロが一意: ゼロの表現は1つだけ(+0と-0がある1の補数とは異なる)。
- 加算がそのまま動作: CPUは符号付きと符号なしの加算に別々の回路を必要としない。
- オーバーフロー検出: 符号ビットへのキャリーインとキャリーアウトが異なる場合、オーバーフローが発生。
符号拡張
2の補数の数値を拡張する場合(例:8ビットから16ビット)、符号ビットをすべての新しい上位ビットにコピー:
-42(8ビット): 11010110
-42(16ビット): 11111111 11010110
これが算術右シフト(>>)の動作です — 符号拡張を実行します。
ユースケース
コンパイラ開発者は整数演算、オーバーフロー検出、型キャストを正しく実装するために2の補数を理解する必要があります。Cプログラムが符号付き8ビット値(-42)を32ビット整数にキャストする場合、コンパイラは符号ビットを上位24ビットにコピーする符号拡張命令を出力します。これを誤ると、負の値が大きな正の数になる微妙なバグが発生します。