私たちは普段 10進数で数を数えますが、コンピュータの内部はすべて 2進数(0 と 1)で動いています。そして、その2進数を人が読み書きしやすくまとめた表記が 16進数です。本記事では、まず「位取り記数法」という共通のしくみを押さえ、2進数・16進数(そして8進数)の考え方、相互変換の具体的な手順、255 = 11111111 = FF といった例までを、検算しながら正確に整理します。
…8 4 2 1、16進数は …256 16 1 と並ぶだけ。コンピュータが2進数を使うのは0と1の2状態が回路で確実に区別できるから、16進数を使うのは1桁がちょうど4ビットで2進数とぴったり対応するからです。
1. 位取り記数法 — すべての基本は「桁の重み」
10進数の 253 が「253」を意味するのは、各桁に重みがあるからです。右から順に 1(10の0乗)、10(10の1乗)、100(10の2乗)…と、桁が一つ上がるごとに重みが 10 倍になります。
例:253 = 2×100 + 5×10 + 3×1 = 200 + 50 + 3
この「桁が上がるごとに何倍になるか」を 基数(base / 底)と呼びます。10進数の基数は 10、2進数は 2、16進数は 16、8進数は 8 です。使う数字(記号)の種類は基数と同じで、10進数なら 0〜9 の 10 種類、2進数なら 0 と 1 の 2 種類です。
- 基数
bの数では、右からk番目(0 始まり)の桁の重みはbのk乗。 - どの基数でも、各桁の数字 × その桁の重みを足し合わせれば値が求まります。
- 同じ「量」でも、基数が違えば見た目(表記)は変わります。たとえば「りんご 11111111 個」と「255 個」は同じ量です。
2. 2進数 — 0 と 1、ビット、なぜコンピュータは2進数なのか
2進数は基数が 2 で、使う数字は 0 と 1 の 2 種類だけです。桁の重みは右から 1, 2, 4, 8, 16, 32, 64, 128… と 2 倍ずつ増えていきます。2進数の 1 桁を ビット(bit)と呼び、8 ビットをまとめた単位が バイト(byte)です。
例:2進数 1101 を10進数に直すと
1101 = 1×8 + 1×4 + 0×2 + 1×1 = 8 + 4 + 0 + 1 = 13
なぜコンピュータは2進数を使うのか
コンピュータの中身は無数の電子回路です。回路の素子(トランジスタ)は、「電圧が高い/低い」「電流が流れる/流れない」という2つの安定した状態を区別するのが得意です。この 2 状態を 1 と 0 に対応させれば、数も文字も命令もすべて表現できます。
- 状態が 2 つだけなら、多少のノイズがあっても
0と1を取り違えにくく、回路を単純・高速・安価に作れます。 - もし 10 段階の電圧で 10 進数を直接扱おうとすると、わずかな電圧の揺らぎで隣の数字と区別できなくなり、信頼性が大きく下がります。
- こうした理由から、コンピュータの内部表現には一貫して 2 進数が使われています。私たちが見ている10進数や文字は、表示の段階で変換された「見せかけ」です。
3. 16進数 — 0〜9とA〜F、1桁=4ビット
16進数は基数が 16 で、1 桁で 0〜15 の 16 通りを表します。10〜15 には数字がないため、A(=10)、B(=11)、C(=12)、D(=13)、E(=14)、F(=15)というアルファベットを当てます。桁の重みは右から 1, 16, 256, 4096… と 16 倍ずつです。
例:16進数 2F を10進数に直すと
2F = 2×16 + F×1 = 2×16 + 15×1 = 32 + 15 = 47
なぜ16進数が便利なのか — 色コードやメモリ表示
16 は 2 の 4 乗なので、16進数の 1 桁がちょうど 2 進数の 4 桁(4 ビット)に対応します。この 4 ビットのまとまりを ニブル(nibble)と呼びます。つまり 2 進数を 4 桁ずつ区切って 16進数に置き換えるだけで、長い 0/1 の列を 4 分の 1 の長さで表記できます。
- 1 バイト(8 ビット)= 16進数 2 桁。たとえば
11111111はFFと短く書けます。 - 色コード:Web の色
#RRGGBBは、赤・緑・青それぞれを 1 バイト(0〜255)で表し、16進数 2 桁ずつ並べたものです。#FF0000は赤が最大(255)・緑と青が 0、つまり純粋な赤です。 - メモリダンプ・アドレス表示:メモリの中身やアドレスは 16進数で表示するのが定番です。バイト境界が 2 桁ごとにそろい、人が読みやすいためです。
4. 8進数にも少し触れておく
8進数は基数が 8 で、使う数字は 0〜7 です。8 は 2 の 3 乗なので、8進数の 1 桁は 2 進数の 3 桁に対応します。かつては 3 ビット単位が扱いやすい場面で広く使われ、現在も Unix/Linux のファイル権限(chmod 755 など)で目にします。
例:8進数 17 を10進数に直すと 1×8 + 7×1 = 8 + 7 = 15。ただし、現代のプログラミングでは 4 ビット単位の 16進数のほうが主流で、8進数の出番は限られます。
5. 相互変換の方法 — 手で計算してみる
基数どうしの変換は、いくつかの決まった手順で確実に行えます。代表的なものを、必ず検算しながら見ていきます。
10進数 → 2進数(割り算の繰り返し)
10進数を 2 で割り、余りを記録する作業を商が 0 になるまで繰り返します。最後に余りを下から上へ読むと 2進数になります。例:13 を 2進数へ。
13 ÷ 2 = 6 余り 16 ÷ 2 = 3 余り 03 ÷ 2 = 1 余り 11 ÷ 2 = 0 余り 1
余りを下から読むと 1101。検算:8+4+0+1 = 13 で一致します。
2進数 → 10進数(重みの掛け算)
各ビットに桁の重み(…8 4 2 1)を掛けて足すだけです。例:1101 = 8 + 4 + 0 + 1 = 13。これは上の割り算の逆操作になっています。
2進数 ↔ 16進数(4桁ずつまとめる)
ここが 16進数の便利なところです。2進数を右から 4 桁ずつ区切り、各 4 桁を 16進数 1 桁に置き換えます(足りなければ左を 0 で埋める)。例:11111111 を 16進数へ。
- 右から 4 桁ずつ区切る:
1111 | 1111。 1111=8+4+2+1 = 15=F。- よって
11111111 = FF。逆にFFは各桁を 4 ビットに展開して1111 1111に戻せます。
10進数
255 = 2進数 11111111 = 16進数 FF = 8進数 377。検算:2進数
11111111 = 128+64+32+16+8+4+2+1 = 255。16進数 FF = 15×16 + 15 = 255。8進数 377 = 3×64 + 7×8 + 7 = 192+56+7 = 255。すべて 255 で一致します。
0〜15 の対応を一覧にすると、2進数・16進数の関係(4 ビット = 1 桁)がよく見えます。
| 10進数 | 2進数(4桁) | 16進数 |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 0101 | 5 |
| 6 | 0110 | 6 |
| 7 | 0111 | 7 |
| 8 | 1000 | 8 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 12 | 1100 | C |
| 13 | 1101 | D |
| 14 | 1110 | E |
| 15 | 1111 | F |
6. 負数とビット幅 — もう一歩だけ深く
ここまでは 0 以上の数(非負整数)だけを扱いました。実際のコンピュータでは、値を入れる「箱」の大きさ=ビット幅があらかじめ決まっています。8 ビット、16 ビット、32 ビット、64 ビットなどです。8 ビットなら表せるのは 0〜255 の 256 通り(2 の 8 乗)です。
- 幅が決まっているため、最大値を超える計算はあふれ(オーバーフロー)を起こします。8 ビットで
255 + 1をすると、桁あふれして0に戻る、という挙動が起こり得ます。 - 負の数を表すために、多くの環境では 2 の補数という方式を使います。一番上のビットを符号の役割に使い、たとえば 8 ビットの符号付き整数では
-128〜127を表します。-1は 8 ビットで11111111と表現されます。 - 同じビットの並び
11111111でも、「符号なし」として読めば255、「符号付き(2 の補数)」として読めば-1になります。どの幅で・どう解釈するかが決まって初めて値が定まる、という点が重要です。
2 の補数や浮動小数点(小数の表し方)は、それ自体が一つのテーマになるほど奥が深いので、ここでは「ビット幅と解釈によって意味が変わる」というところまで押さえれば十分です。
Free Tool 基数変換ツールで実際に変換する 10進数・2進数・16進数・8進数を相互に変換できます。本文の例(255 = 11111111 = FF = 377)も、その場で入力して確かめられます。よくある質問(FAQ)
なぜコンピュータは2進数を使うのですか?
コンピュータの基本部品であるトランジスタやメモリ素子は「電圧が高い/低い」「電流が流れる/流れない」といった2つの安定した状態を確実に区別するのが得意だからです。状態が2つなら、わずかなノイズがあっても0と1を取り違えにくく、回路を単純で高速・安価に作れます。10通りの電圧レベルを正確に区別するより、2通りを区別するほうがはるかに信頼性が高いため、内部表現には2進数が使われます。
16進数はなぜ使うのですか?
16進数の1桁がちょうど4ビット(2進数4桁)に対応し、2進数と相互変換しやすいからです。長くて読みにくい2進数を、4桁ずつまとめて短く表記できます。たとえば8ビット(1バイト)は16進数2桁で表せます。メモリダンプ、色コード(#RRGGBB)、文字コード、MACアドレスなどで、人が読み書きしやすい表記として広く使われています。
なぜ255は16進数でFFになるのですか?
16進数では1桁で0〜15を表し、Fが15を意味します。FFは上の桁が15×16=240、下の桁が15で、合わせて240+15=255になります。255は8ビットで表せる最大値(2進数では11111111)であり、ちょうど16進数2桁の最大値FFと一致します。このため1バイト=16進数2桁という対応が成り立ち、色コードなどで255がFFとして現れます。