日々のプログラミングでは、2進数と16進数を行き来しながら10進数の感覚で考える場面が頻出します。
基本のしくみと変換のコツをひとまとめに理解しておくと、デバッグやビット演算、プロトコル解析が一気にスムーズになります。
本記事では、初心者の方でも迷わないように、表と手順を使って丁寧に解説します。
基本: 2進数・10進数・16進数のしくみ
基数(2/10/16)と桁の意味
数の表現は「基数」によって桁の重みが変わるという点が最重要です。
10進数は各桁が10の累乗、2進数は2の累乗、16進数は16の累乗として重みが割り当てられます。
例えば10進数の123は、100の位が10^2、10の位が10^1、1の位が10^0で構成されます。
用語の整理
2進数は0と1のみ、16進数は0〜9とA〜Fの16種類の「数字」を使います。
16進数のA
〜F
は、それぞれ10〜15を表します。
プログラミングではこれらを数値として扱うため、文字と数の対応を頭の中で素早く変換できると便利です。
桁が1つ左に移動するたびに基数分だけ重みが増えるというイメージを持つと理解が定着します。
桁の重みのイメージ
それぞれの桁は「基数のべき乗」を重みとして持ちます。
2進数101101
なら、右端から2^0, 2^1, 2^2, ...
の重みが並び、1が立っている桁の重みを合計します。
16進数2A
なら、216^1 + 1016^0
です。
「桁の重みを足す」だけと覚えると変換は怖くありません。
2進数と16進数の関係(4ビット=1桁)
16進数1桁は2進数4ビット(ニブル)にぴったり対応します。
理由は16 = 2^4
だからです。
この性質のおかげで、2進数と16進数の相互変換は機械的に行えます。
グループ化のやり方
2進数を右から4ビットずつ区切り、各グループを16進数1桁に置き換えます。
ビット数が4の倍数でなければ、左端に0を足して4の倍数に揃えます。
逆方向は、16進数の各桁をそれぞれ4ビットの2進数に展開するだけです。
必ず右端から区切るのが安定した変換のコツです。
なぜ便利か
2進数の長い列を短く読みやすくでき、メモリやレジスタの内容を人間に優しい形で扱えるからです。
データサイズの見積もりやビットマスクの設計でも、16進表記は視認性と正確さの両立に役立ちます。
変換表(初心者向け)
0〜15の変換表(2進数/10進数/16進数)
まずは0〜15を丸暗記すると、2進数↔16進数の変換が一気に楽になります。
2進数は4ビットでゼロ埋めしてあります。
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 |
2の累乗の目安(1,2,4,8,16…)
2の累乗は境界値や桁上がりの感覚づくりに不可欠です。
10進と16進の両方で眺めると、感覚が早く身につきます。
n | 2^n(10進) | 16進 |
---|---|---|
0 | 1 | 0x1 |
1 | 2 | 0x2 |
2 | 4 | 0x4 |
3 | 8 | 0x8 |
4 | 16 | 0x10 |
5 | 32 | 0x20 |
6 | 64 | 0x40 |
7 | 128 | 0x80 |
8 | 256 | 0x100 |
9 | 512 | 0x200 |
10 | 1024 | 0x400 |
11 | 2048 | 0x800 |
12 | 4096 | 0x1000 |
13 | 8192 | 0x2000 |
14 | 16384 | 0x4000 |
15 | 32768 | 0x8000 |
16 | 65536 | 0x10000 |
変換方法(手順とコツ)
2進数→10進数(桁の重みを足す)
「1のある桁の重みを合計する」だけです。
右端のビットから2^0, 2^1, ...
と割り当てます。
例: 2進数101101を10進数に
101101(2)の各桁の重みは1,2,4,8,16,32です。
1の立っている位置は32, 8, 4, 1
なので、合計32 + 8 + 4 + 1 = 45
、答えは45です。
0の桁は無視して良い点がシンプルさの理由です。
暗算のコツ
大きめの2の累乗に寄せると早くなります。
例えば11001010(2) = 128 + 64 + 8 + 2 = 202
。
また、4ビットごとに区切って16進に直してから10進へ換算しても計算量が減ります。
10進数→2進数(割り算と余り)
2で割り続けて余りを逆順に読むのが定番です。
余りは常に0か1です。
手順と例: 45を2進数に
45 ÷ 2の商と余りを順に取り、最後に余りを下から上へ読むと101101
になります。
計算は45→22 r1→11 r0→5 r1→2 r1→1 r0→0 r1
で、余りを逆順に並べて101101
です。
ショートカット
最大の2の累乗を引く分解法も便利です。
45なら32(2^5)
を引いて残り13、次に8(2^3)
、4(2^2)
、1(2^0)
で、ビット位置5,3,2,0
が1、すなわち101101
です。
16進数→10進数(16の重みを足す)
16のべき乗を重みとして各桁を展開します。
例: 0x2A3を10進数に
0x2A3は216^2 + 1016^1 + 316^0なので、2256 + 1016 + 3 = 512 + 160 + 3 = 675
です。
小さな例では0x3F = 316 + 15 = 63
と一瞬で出せます。
10進数→16進数(割り算と余り)
16で割り続けて余りを逆順に読む基本は2進数と同じです。
余り10〜15はA〜F
に置き換えます。
例: 2748を16進数に
2748 ÷ 16 = 171 r12(C)、171 ÷ 16 = 10 r11(B)
、10 ÷ 16 = 0 r10(A)
。
余りの逆順で0xABC
です。
255なら0xFF
と定番の結果になります。
2進数↔16進数(4ビットごとに変換)
右から4ビットずつ区切れば、対応表だけで瞬時に変換できます。
2進数→16進数の例
1010 1101 1110(2)は、1010=A, 1101=D, 1110=Eなので0xADE
です。
桁数が111
のように3ビットなら、左に0を足して0111
と見なして0x7
にします。
16進数→2進数の例
0xA3はA=1010, 3=0011なので1010 0011
です。
各16進桁を独立に4ビットへ展開するだけです。
プログラミングでの表記と注意点
0b/0xの接頭辞(2進数/16進数)
多くの言語で2進数は0b
、16進数は0x
を先頭につけて数値リテラルとして書けます。
例は0b1010 == 10
、0xFF == 255
です。
PythonやJava、C/C++、JavaScriptなどで共通です。
読みやすさ向上のために0b1010_1100
のようにアンダースコアで区切りが許される言語もあります。
大文字/小文字(A〜F)
16進のA〜Fは大文字小文字を区別しないのが一般的です。
0xff
も0xFF
も同じ255です。
ただし、出力の書式では%x
は小文字、%X
は大文字といった違いがあります。
表記ゆれは意味を変えないが、スタイルは統一すると読みやすくなります。
先頭の0の扱い(値は同じ)
先頭の0は値を変えません。
0x0F
は0xF
と同じ15、0b0011
は0b11
と同じ3です。
ただし一部言語では先頭の0で8進数扱いになる歴史的仕様があります(例: C系の0123
は8進数)。
混乱を避けるため、10進数の整数リテラルを0で始めないことを推奨します。
よくあるミスとチェック方法
「順序」と「桁の位置」を取り違えるミスが最も多いです。
以下の観点でセルフチェックすると安全です。
- 余りの並び順を逆に読んでいないか(10進→2進や→16進でよく発生)。
- 2進→16進のグループ化で左から区切っていないか(必ず右から4ビット)。
- 16進の
G
など存在しない文字を使っていないか(A〜Fのみ)。 - ビットとバイトを混同していないか(1バイト=8ビット、16進2桁=1バイト)。
- 先頭0の取り扱いによる誤解がないか(特に8進数の暗黙解釈)。
チェックには、往復変換で確かめるのが有効です。例えばPythonならint('101101', 2) == 45
、format(45, 'b') == '101101'
、format(45, 'x') == '2d'
で相互に検証できます。OS標準の電卓の「プログラマー」モードやbc
、node
、python
のREPLも役立ちます。
まとめ
2進数・10進数・16進数の要は「桁の重み」と「4ビット=16進1桁」の2点です。
0〜15の対応表を覚え、2の累乗の目安を肌感覚で掴めば、どの方向の変換も一瞬で判断できるようになります。
実務では右からの4ビットグループ化や割り算と余りの逆順読みを機械的に適用し、最終確認として往復変換やプログラマーモード電卓で検証する習慣を持つと堅牢です。
基礎を習得すれば、ビット演算やデータ表現の理解が進み、エラーの早期発見や高速なデバッグに直結します。