更新:2024/12/30

2の補数と負の数の表現の意味と計算問題について

はるか
はるか
コンピュータで数値を「0と1」で表現するのはわかるけど、負の数は?
ふゅか
ふゅか
いい質問ね!負の数を表現するには「補数」って方法が使われてるのよ。これが結構面白いんだから!

1. はじめに

コンピュータの世界では、数値を「0と1」の組み合わせ(2進数)で表現します。しかし「正の数」だけならまだしも、「負の数」をどうやってこの0と1で表現するのかは、最初は意外とピンとこないですよね。その仕組みを理解するうえで欠かせないのが「2の補数」という概念です。

2. 2の補数とは?

補数には補う数という意味があります。そして、コンピュータの世界では、2の補数は、負の数を表すために利用される方法です。例えば、8ビット(0と1が8つ並んだもの)で整数を表現する場合、次のようなルールを使います。

  1. 正の数(および0)は通常通りの2進数で表す
    • 例: 8ビットで 5 は 00000101 となる
  2. 負の数は「2の補数」という変換ルールによって表す
    • 例: -5 を表現したいときは、まず +5 の2進数(00000101)を用意し、それを反転(ビットを0→1、1→0)して、さらに 1を足す という手順で求めます。
      • +5 = 00000101
      • 反転すると 11111010
      • そこに +1 すると 11111011
  3. 2の補数と元の数の計算
    • 5を2進数で表現した例を使って、0000010111111011の足し算を行うと・・・
      100000000となります。
    • つまり 8ビットの世界では10000000000000000になるわけです。
      したがって、足して0になるので、8ビットにおいて、11111011 が -5 を表すようになるわけです。
はるか
はるか
反転して1を足す…やってみないとピンと来ない。
ふゅか
ふゅか
じゃあ、+5と-5を例に説明するね!+5はそのまま「00000101」、これを反転して「11111010」にして、さらに1を足すと「11111011」になるの!

3. 負の数を扱うための工夫

なぜわざわざビットの反転と1の加算という手間をかけるのでしょうか? その理由のひとつは、「足し算と引き算を同じような仕組みで処理したい」というコンピュータ的な都合にあります。

  • 例を挙げると、2の補数方式では、(正の数) + (負の数) が自然と引き算になるのです。
  • たとえば 5 + (-3) を 8ビット上で計算すると、 00000101(= +5) と 11111101(= -3) を足し算すると、結果は 0000010(1) となり(先頭の桁は桁あふれするため無視)、最終的に 00000010(= 2)となって、期待どおり「2」という結果が得られます。

このように、2の補数方式を使うと、わざわざ「引き算専用の回路」を持たなくても、足し算の機能だけで正負含めて計算ができるようになるのです。

4. 計算問題

4.1. \( 15 – 27 \) を計算しなさい。

  1. 数値の表現
    • \( 15 \) を8ビットの2進数で表現: \( 00001111 \)
    • \( 27 \) を8ビットの2進数で表現: \( 00011011 \)
  2. 減算を加算に変換
    減算 \( 15 – 27 \) は、\( 15 + (-27) \) に置き換えます。
  3. \( -27 \) を2の補数で表現
    1. \( 27 \) のビット反転: \( 11100100 \)
    2. ビット反転した値に1を加える: \( 11100101 \) → これが \( -27 \) を表す2の補数表現。
  4. 加算
    \( 00001111 + 11100101 \):
      00001111
    + 11100101
    ------------
      11110100
    
  5. 結果の確認
    \( 11110100 \) は負の数です。これを10進数に戻して、数値が正しいか確認します。
    1. ビット反転: \( 00001011 \)
    2. 1を加える: \( 00001100 \) → \( 12 \)

    結果は \( -12 \) です。

4.2. \( -30 + 18 \) を計算しなさい。

  1. 数値の表現
    • \( -30 \) を8ビットの2進数で表現: \( 11100010 \)(\( 30 \) をビット反転し、1を加えた結果)
    • \( 18 \) を8ビットの2進数で表現: \( 00010010 \)
  2. 加算\( 11100010 + 00010010 \):
      11100010
    + 00010010
    ------------
      11110100
    
  3. 結果の確認
    \( 11110100 \) は負の数です。これを10進数に戻して、数値が正しいか確認します。
    1. ビット反転: \( 00001011 \)
    2. 1を加える: \( 00001100 \) → \( 12 \)

    結果は \( -12 \) です。

PR