
2026年10月18日に全面リライトしました
2023年7月に公開した記事を、「つくって学ぶ」の趣旨に合わせて書き直した。C言語のプログラムで、負数を表すしくみを実際に確認できる内容になっている。
はじめに
コンピューターは、0と1だけで情報を表す。では、マイナスの数は、どのように表すのだろうか。その答えが「2の補数」である。
今回は、補数の考え方を整理してから、C言語のプログラムで、4ビットや8ビットの数を実際に表示して確かめよう。
4ビットで表せる数
4ビットでは、2⁴ = 16通りの組み合わせがある。これを、0以上の2進数に対応させると、0000〜1111(0〜15)を表せる。
しかし、これでは負数を表せない。負数をどう表すかは、コンピュータの設計者が決める。
かつては1の補数が使われていたが、現在の多くのコンピュータは、2の補数を使っている。
補数とは
補数(ほすう)とは、与えられた数を、ある決められた数から引いて得られる数のことである。
まず、10進数で考えてみよう。
- 10の補数:足すと桁が上がる最小の数(10)になる。「7」の補数は「3」(7 + 3 = 10)
- 9の補数:足しても桁が上がらない最大の数(9)になる。「7」の補数は「2」(7 + 2 = 9)

これを、nビットの2進数に当てはめる。
- 2の補数:2ⁿ から元の数を引いた数(4ビットなら、
10000− 元の数) - 1の補数:2ⁿ − 1 から元の数を引いた数(4ビットなら、
1111− 元の数。ビットを反転した数と同じ)
2の補数は、「ビットを反転して、1を足す」ことでも求められる。たとえば「3」の場合、次のようになる。
0011(3) → 反転 → 1100 → 1を足す → 1101
1101 は、10進数で13であり、16 − 3 と一致している。この 1101 が、4ビットの「−3」を表す。
2の補数を使う最大のメリットは、マイナス記号を使わずに、負数を表現できる点である。
符号ビット
負数を2の補数で表すと、表現できる値の範囲が変わる。一番左のビットが符号ビットになり、1のときは負数を表す。
| 範囲 | 4ビットの例 | |
|---|---|---|
| 正整数だけ | 0 〜 2ⁿ − 1 | 0 〜 15 |
| 2の補数 | −2ⁿ⁻¹ 〜 +2ⁿ⁻¹ − 1 | −8 〜 +7 |
体験1:C言語で4ビットの全パターンを表示する
−8〜+7を、4ビットの2進数で表示しよう。下記のコードをbits4.c で保存して実行しよう。
#include <stdio.h>
int main(void) {
printf("値 4ビット 16+値\n");
for (int v = -8; v <= 7; v++) {
unsigned bits = (unsigned)v & 0xF; /* 下位4ビットだけ取り出す */
printf("%2d ", v);
for (int i = 3; i >= 0; i--) {
putchar(((bits >> i) & 1) ? '1' : '0');
}
if (v < 0) {
printf(" %2d", 16 + v);
}
putchar('\n');
}
return 0;
}gcc bits4.c -o bits4
./bits4実行結果の一部は、次のようになる。
値 4ビット 16+値
-8 1000 8
...
-3 1101 13
-2 1110 14
-1 1111 15
0 0000
1 0001
...
7 0111
確認するポイントは、次の3つである。
- 負数は、すべて左端のビット(符号ビット)が1になる
- 負数の2進数を、普通の数として読むと、「16 + 値」と同じ数になる(−3 → 13)
- 表せる範囲は、−8〜+7である
体験2:範囲をはみ出すとどうなるか?C言語で試してみよう
次は、8ビットの整数で、最大値に1を足してみよう。下記のコードをoverflow8.c で保存して実行しよう。
#include <stdio.h>
#include <stdint.h>
int main(void) {
printf("8ビットの範囲: %d 〜 %d\n", INT8_MIN, INT8_MAX);
int8_t x = INT8_MAX;
printf("最大値 : %d\n", x);
x = (int8_t)(x + 1);
printf("1を足すと : %d\n", x);
return 0;
}gcc overflow8.c -o overflow8
./overflow8実行結果は、次のようになる。
8ビットの範囲: -128 〜 127
最大値 : 127
1を足すと : -128
8ビットで表せる範囲は、−128〜+127である(n = 8 を、先ほどの式に当てはめた値)。
最大値の127(01111111)に1を足すと、10000000 になり、符号ビットが1になるため、−128になる。
このように、8ビットで表せる範囲を超えると、意図した値とは異なる値になることがある。
今回のプログラムでは、gccを使うと −128 が表示される。
まとめ
- 補数とは、ある決められた数から、元の数を引いた数である
- 現在の多くのコンピューターは、負数を2の補数で表す
- 2の補数は、「ビットを反転して、1を足す」ことでも求められる
- 負数は符号ビットが1になり、nビットで −2ⁿ⁻¹ 〜 +2ⁿ⁻¹ − 1 を表せる
- 範囲をはみ出すと、符号が逆転した値になる
次に読む
基本情報技術者試験の問題を、Pythonで確かめてみよう。
→ 基本情報技術者試験問題に挑戦しよう!(2の補数)~Pythonでつくって確かめる~【GitHub対応】
更新履歴
- 2026年10月18日:全面リライト(手を動かす内容に刷新)
- 2023年7月6日:初版公開




コメント