2の補数表現

コンピュータが2の補数を使用して負の整数を表現する方法を学びます。NOT、加算、符号付き数値の関係を理解します。

Number Representation

詳細な説明

2の補数:コンピュータが負の数を格納する方法

2の補数は最新のコンピュータで符号付き整数を表現する普遍的な方法です。同じ加算回路が正と負の両方の数で動作することをエレガントに可能にします。

2の補数の計算方法

2の補数で数値を否定するには:

  1. すべてのビットを反転(ビットNOT)
  2. 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. ゼロが一意: ゼロの表現は1つだけ(+0と-0がある1の補数とは異なる)。
  2. 加算がそのまま動作: CPUは符号付きと符号なしの加算に別々の回路を必要としない。
  3. オーバーフロー検出: 符号ビットへのキャリーインとキャリーアウトが異なる場合、オーバーフローが発生。

符号拡張

2の補数の数値を拡張する場合(例:8ビットから16ビット)、符号ビットをすべての新しい上位ビットにコピー:

-42(8ビット):  11010110
-42(16ビット): 11111111 11010110

これが算術右シフト(>>)の動作です — 符号拡張を実行します。

ユースケース

コンパイラ開発者は整数演算、オーバーフロー検出、型キャストを正しく実装するために2の補数を理解する必要があります。Cプログラムが符号付き8ビット値(-42)を32ビット整数にキャストする場合、コンパイラは符号ビットを上位24ビットにコピーする符号拡張命令を出力します。これを誤ると、負の値が大きな正の数になる微妙なバグが発生します。

試してみる — Bitwise Calculator

フルツールを開く