第一回の補足(2の補数表現)

第一回で整数の2の補数表現について説明した. その補足をすこし.
2の補数表現が, 「なぜ」あのように決まっているのか.

負の整数を表すための表現として, 2の補数表現を紹介した. たとえば,

+3 -> 00000011
-3 -> 11111101
となる約束だった. で, これらふたつの数を, 符号を無視して, つまり符号なしの二進数として 足し算するとどうなるか.
00000011 + 11111101 -> 1 00000000
足し算の結果の9ビットめは, 繰り上がりを示している. で, この繰り上がりを無視すると, 結果は 0 になる. これは, 「3 + (-3) = 0」を示している.

つまり, 足し算や引き算において, 正負の符号を無視して計算しても, ちゃんと結果のつじつまがあうように, 2の補数表現 は決められているのだった. 3+(-2)とか, (-1)+(-2)などを試してみるとよい.


つぎ, 前回示したいくつかの質問の解説. ( 第一回のそのページ )

  1. 一番左のビット(最上位ビット, MSB - Most Significant Bit) が 1 である 数に共通する性質は何だろう?

    -1 が 11111111, -2 が 11111110, ... -128 が 10000000, というわけで, 「負の数」がこたえでした. その意味で, 一番左のビットを「符号ビット」と呼ぶこともあります.

  2. 一番右のビット(最下位ビット, LSB - Least Significant Bit) が 1 である 数に共通する性質は何だろう?

    まず 1 は 00000001 だから, 最下位ビットは 1. つぎに, それに 2 を加えた 3 (00000011) もそう. さらに, それに 2 を加えた 5 (00000101) もそう. ... というわけで, 1 に次々に 2 を加えていって得られる数, すなわち「奇数」が こたえでした.

  3. 正数 n の2の補数表現から, (-n) の2の補数表現をつくるには, どうすればいいだろう?

    3 は 00000011, -4 は 11111100 となるので, これらはちょうど 1 と 0 を 反転した形をしている. つまり,
    「正数 n の各ビットの 1 と 0 を反転すると -(n+1) となる」
    わけだから, もうひとひねりすれば
    「正数 n の各ビットの 1 と 0 を反転して 1 をたすと -n となる」
    で, これがこたえ.

    さらにいえば, 負の数に対してこの操作をすると, ちゃんと正数になる.

  4. ある数を 1 ビット左にずらして右端に 0 をいれると, どんな数が得られるだろう?

    早速やってみる. (ビットをずらすのを, シフトする ともいう.)

    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進数なら自明ですな)

  5. ある数を 1 ビット右にずらして左端に 0 をいれると, どんな数が得られるだろう?

    これもやってみる.

    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で割った商(ただしあまりを正にとる)で, 首尾一貫するのに, というわけで...

  6. ある数を 1 ビット右にずらして左端には元の左端と同じものをいれると, どんな数が得られるだろう?

    これが「2で割った商 (ただしあまりを正にとる)」の求め方でした.

  7. ある数の右端の 2 ビットを全部 0 にしてしまうと, どんな数が得られるだろう?

    これもやってみる.

    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単位に切り捨てたことになるのと 同じですな.

  8. ある数の右端の 2 ビット以外を全部 0 にしてしまうと, どんな数が得られるだろう?

    これもやってみる.

    00000000 -> 00000000 (0 -> 0)
    00000001 -> 00000001 (1 -> 1)
    00000010 -> 00000010 (2 -> 2)
    00000011 -> 00000011 (3 -> 3)
    00000100 -> 00000000 (4 -> 0)
    
    これは「4で割ったあまり」がこたえ. 負の数の場合も同様.

    10進数において, 下二桁をとりだすと, 100で割ったあまりになるのに相当する.

  9. ある数の2の補数表現における, 「1となっているビットの個数」には何か意味があるだろうか?

    これもやってみる.

    00000000 (0 -> 0)
    00000001 (1 -> 1)
    00000010 (2 -> 1)
    00000011 (3 -> 2)
    00000100 (4 -> 1)
    
    というわけで, あまり意味はなさそうですねえ...


[page 6] prev index next