負数を表現する2の補数表現
負数を表現するための2の補数表現について解説します。
8bit符号あり整数型のint8_tの例で解説します。
コンピューターアーキテクチャでは、負の数を表現する方法が、いくつかあります。2の補数表現は、その一つです。
2の補数表現を具体的に書き出してみます。
負の数 | 負の数のビット表現 | 正の数(0含む) | 正の数のビット表現 |
-1 | 11111111 | 0 | 00000000 |
-2 | 11111110 | 1 | 00000001 |
-3 | 11111101 | 2 | 00000010 |
... | ... | ... | ... |
-126 | 10000010 | 125 | 01111101 |
-127 | 10000001 | 126 | 01111110 |
-128 | 10000000 | 127 | 01111111 |
2の補数表現の特徴を見てみましょう。
- 最上位ビットが0の場合は正数。最上位ビットが1の場合は負数
- 127(正の最大値)は01111111
- -1は、11111111
- -128は、10000000
- ビットを反転させて和をとると-1(11111111)になる
2の補数の定義は、どこにでも解説があるので、調べてみてくださいね(笑)。
負数は2の補数表現であると想定してもかまいませんか?
C言語仕様では、負数は2の補数であるとは、定義されていませんが、実際の多くの処理系では、負数の表現は、他の表現よりも、2の補数であるほうがずっと多いと考えます。
正の最大値に1を加えたときに、負の最小値になるのであれば、処理系が負数に2の補数表現を使っていると確信できます。
数値計算ライブラリが、処理系に負数の表現が2の補数であることを求めるのであれば、簡単な計算でチェックできます。
2の補数の特徴は何ですか?
2の補数の特徴は、引き算を足し算で表現できることです。
2 - 3 = -1
これは以下と同じ。
# 00000010 + 11111101 = 11111111 2 + (-3) = -1
どこらへんに2の補数の2というニュアンスがあるのですか?
名前の付け方が、まずかったのかもしれません...。
無理やりこう考えます。
第一番目に発見された補数を、1の補数と呼びましょう。単なるビット反転で、符号が変わります。
第二番目に発見された補数を、2の補数と呼びましょう。単なるビット反転に、1を足す操作を加えると、符号が変わります。