負の整数を表すための表現として, 2の補数表現を紹介した. たとえば,
+3 -> 00000011 -3 -> 11111101となる約束だった. で, これらふたつの数を, 符号を無視して, つまり符号なしの二進数として 足し算するとどうなるか.
00000011 + 11111101 -> 1 00000000足し算の結果の9ビットめは, 繰り上がりを示している. で, この繰り上がりを無視すると, 結果は 0 になる. これは, 「3 + (-3) = 0」を示している.
つまり, 足し算や引き算において, 正負の符号を無視して計算しても, ちゃんと結果のつじつまがあうように, 2の補数表現 は決められているのだった. 3+(-2)とか, (-1)+(-2)などを試してみるとよい.
-1 が 11111111, -2 が 11111110, ... -128 が 10000000, というわけで, 「負の数」がこたえでした. その意味で, 一番左のビットを「符号ビット」と呼ぶこともあります.
まず 1 は 00000001 だから, 最下位ビットは 1. つぎに, それに 2 を加えた 3 (00000011) もそう. さらに, それに 2 を加えた 5 (00000101) もそう. ... というわけで, 1 に次々に 2 を加えていって得られる数, すなわち「奇数」が こたえでした.
3 は 00000011, -4 は 11111100 となるので, これらはちょうど 1 と 0 を
反転した形をしている.
つまり,
「正数 n の各ビットの 1 と 0 を反転すると -(n+1) となる」
わけだから, もうひとひねりすれば
「正数 n の各ビットの 1 と 0 を反転して 1 をたすと -n となる」
で, これがこたえ.
さらにいえば, 負の数に対してこの操作をすると, ちゃんと正数になる.
早速やってみる. (ビットをずらすのを, シフトする ともいう.)
00000000 -> 00000000 (0 -> 0) 00000001 -> 00000010 (1 -> 2) 00000010 -> 00000100 (2 -> 4) 00000011 -> 00000110 (3 -> 6)というわけで, どうやら二倍になりそう. 負の数はどうかというと
11111111 -> 11111110 (-1 -> -2) 11111110 -> 11111100 (-2 -> -4) 11111101 -> 11111010 (-3 -> -6)というわけで大丈夫そう.
じつは, これは一般的には
「n 進数は, 末尾に 0 をつけると n倍になる」
ということなのでした. (10進数なら自明ですな)
これもやってみる.
00000000 -> 00000000 (0 -> 0) 00000001 -> 00000000 (1 -> 0) 00000010 -> 00000001 (2 -> 1) 00000011 -> 00000001 (3 -> 1) 00000100 -> 00000010 (4 -> 2)というわけで, 2で割った商(の整数部)になりそう. では負数ではどうかというと
11111111 -> 01111111 (-1 -> 127)左端に 0 が入ってしまうと, 負の数が正数になってしまうので, 具合が悪い. 負の数の場合に限って, 左からは 1 が入ってくれば
11111111 -> 11111111 (-1 -> -1) 11111110 -> 11111111 (-2 -> -1) 11111101 -> 11111110 (-3 -> -2) 11111100 -> 11111110 (-4 -> -2)で, 2で割った商(ただしあまりを正にとる)で, 首尾一貫するのに, というわけで...
これが「2で割った商 (ただしあまりを正にとる)」の求め方でした.
これもやってみる.
00000000 -> 00000000 (0 -> 0) 00000001 -> 00000000 (1 -> 0) 00000010 -> 00000000 (2 -> 0) 00000011 -> 00000000 (3 -> 0) 00000100 -> 00000100 (4 -> 4)というわけで, 「4で割ったあまりを捨てた数」がこたえ. 「内輪で最も近い 4の倍数」といういい方もできる. 負の数の場合には
11111111 -> 11111100 (-1 -> -4) 11111110 -> 11111100 (-2 -> -4) 11111101 -> 11111100 (-3 -> -4) 11111100 -> 11111100 (-4 -> -4) 11111011 -> 11111000 (-5 -> -8)で, 「あまりを正にとる」と考えると首尾一貫している.
10進数において, 下二桁を 0 にすると, 100単位に切り捨てたことになるのと 同じですな.
これもやってみる.
00000000 -> 00000000 (0 -> 0) 00000001 -> 00000001 (1 -> 1) 00000010 -> 00000010 (2 -> 2) 00000011 -> 00000011 (3 -> 3) 00000100 -> 00000000 (4 -> 0)これは「4で割ったあまり」がこたえ. 負の数の場合も同様.
10進数において, 下二桁をとりだすと, 100で割ったあまりになるのに相当する.
これもやってみる.
00000000 (0 -> 0) 00000001 (1 -> 1) 00000010 (2 -> 1) 00000011 (3 -> 2) 00000100 (4 -> 1)というわけで, あまり意味はなさそうですねえ...