GUZAI3ノートブック

友人であるGUZAI3様の依頼で備忘録を書いています。

2の補数で負の整数を表すこと

符号付き整数の負数と2の補数について理解したことのメモ。
※ここでは、「正の整数」は0も含むものとする。

8ビット符号付き整数を考えてみる。

まず8ビットで表現できる2進数は、0000 0000~1111 1111となる。
ただし最上位ビットは符号として扱う。

最上位ビット 符号
0
1

すると、表現可能な整数は以下のようになる。

正の整数 0000 0000~0111 1111
負の整数 1000 0000~1111 1111

ここに10進数を対応させれば良い。
まずは正の整数。0はここに割り当てる。

2進数 0000 0000 0000 0001 ~ 0111 1111
10進数 0 1 ~ 127

これは問題なさそう。

次は負の整数。
0は正の整数で表現したので、-1から割り当てる。

2進数 1000 0000 1000 0001 ~ 1111 1111
10進数 -1 -2 ~ -128

これも問題なさそう...と最初は認識していた。(学び始めは!)

...実はこれ、問題がある。
一般的(?)な整数の演算を考えた場合、1 - 1 = 1 + (-1) = 0となるはず。
では、上記の整数表現で2進数を考えたらどうなるか。

10進数 1 + (-1) = 0
2進数 0000 0001 + 1000 0000 = 1000 0001

2進数の計算結果が、明らかにおかしい...
10進数と2進数は表現の違いだけなので、2進数の計算結果も 0000 0000 になってほしい。

ここで、10進数と2進数の対応を見直す。

負の整数表現を修正する。

計算結果が 0000 0000 (10進数の0) になるためには、どのような値を加算すればよいのか。

まずは、次の計算を考えてみる。
1111 1111 + 0000 0001 = 1 0000 0000

『計算結果を見ると、1のビットがある。10進数の0では無さそうだ...』
と、考えるのは待ってほしい。

もともと8ビットの世界で進めていた話だ。
9ビット目は認識できない世界なので、無視しよう!!

改めて、計算は以下のようになる。
1111 1111 + 0000 0001 = 0000 0000

結果が0になった。嬉しい!!!

これを利用すると、負の整数は以下のように対応させれば良さそうだ。

2進数 1000 0000 1000 0001 ~ 1111 1111
10進数 -128 -127 ~ -1

(検算1)
127 - 127
= 127 + (-127)
= 0111 1111 + 1000 0001
= 0111 1111 + 1000 0000 + 0000 0001
= 1111 1111 + 0000 0001
= 0000 0000

(検算2)
56 -56
= 56 + (-56)
= 0011 1000 + 1100 1000
= 0011 1000 + 1100 0111 + 0000 0001
= 1111 1111 + 0000 0001
= 0000 0000

確かに問題ない。

正と負の関係を考えてみる。

負の整数を2進数で表すことはできた。

10進数で言うところの、マイナス倍はどのように捉えればよいか。
例えば 56 * (-1) = -56 のように、符号だけ付け替えること。

検算をよく観察すると、以下のように考えれば良さそうだ。

127を-127にする。
(127=) 0111 1111 →(ビット反転)→ 1000 0000 →(1加算)→ 1000 0001 (= -127)

56を-56にする。
(56 =) 0011 1000 →(ビット反転)→ 1100 0111 →(1加算)→ 1100 1000 (= -56)

操作の目的は、元の値に加算すると 0000 0000 になる値へ変換すること。

  • ビット反転後は、元の値に加算すると 1111 1111 となる。
  • さらに1を加えた値は、元の値に加算すると 0000 0000 となる。

この操作で問題なさそうだ。

ちなみに、負の整数を正の整数にも変換できる。
(-76=)1011 0100 →(ビット反転)→ 0100 1011 →(1加算)→ 0100 1100 (= 76)

つまり、2進数のマイナス倍は「ビット反転して1加算」で操作できる!!!

2の補数

このビット反転で得られた値には、名前がある。

操作 得られる値の名前
整数Aをビット反転 Aの1の補数
整数Aをビット反転して1加算 Aの2の補数

負の整数は、正の整数の2の補数を考えれば良いということになる。
なるほど~
ちなみに、ビット反転で解決することは、コンピュータ的には簡単で嬉しいらしい。
(電気信号のON↔OFFを変えれば済むので。)

つぶやき

整数について勉強したときに「なんで負の整数は2の補数なんや!!!」と思いつつ、放置してた。
なんとなく考えてたら分かってきたので、備忘録として書いた。
鍵は、「足して0にする。」という考え方だと思う。
雰囲気としては、群論の逆元の概念で理解したつもり。