コンピューターサイエンスやプログラミングを学ぶうえで、「進数変換」は避けて通れない重要なテーマのひとつです。
私たちが日常的に使っている「10進数」以外にも、コンピューターの世界では「2進数」「8進数」「16進数」が頻繁に登場します。
しかし、「なぜ複数の進数があるのか?」「どうやって変換するのか?」と問われると、うまく説明できない方も少なくないでしょう。
本記事では、進数変換の基本的な仕組みから、2進数・8進数・16進数への具体的な変換方法、小数の変換、よくある問題の解き方まで、できるだけわかりやすく丁寧に解説していきます。
情報処理の試験対策から、プログラミングの基礎固めまで、幅広くお役に立てる内容を目指していますので、ぜひ最後までご覧ください。
進数変換の基本:「何を基準に位取りするか」が進数の本質
それではまず、進数変換の基本的な概念と仕組みについて解説していきます。
進数とは「何個ごとに一つ上の位に繰り上げるか」を決める数の表現システムであり、n進数ではn個集まると一つ上の位に繰り上がります。
私たちが普段使う10進数では、0から9の10種類の数字を使い、10個集まると次の位(十の位)に繰り上がります。
同様に、2進数では0と1の2種類の数字を使い、2個集まると次の位に繰り上がります。
16進数では0〜9とA〜Fの16種類の数字を使い、16個集まると次の位に繰り上がります。
【各進数で使用する数字と基数】
■ 2進数(binary):0, 1(基数2)
■ 8進数(octal):0, 1, 2, 3, 4, 5, 6, 7(基数8)
■ 10進数(decimal):0, 1, 2, 3, 4, 5, 6, 7, 8, 9(基数10)
■ 16進数(hexadecimal):0〜9, A, B, C, D, E, F(基数16)
16進数でA=10、B=11、C=12、D=13、E=14、F=15に対応します。
n進数の数値は、各桁の数字に「基数のべき乗」を掛けて足し合わせることで10進数に変換できます。
たとえば2進数の1101₂を10進数に変換すると、1×2³ + 1×2² + 0×2¹ + 1×2⁰ = 8 + 4 + 0 + 1 = 13₁₀となります。
「位取り記数法」の本質は、各桁の重み(基数のべき乗)を理解することであり、これが進数変換のすべての出発点です。
なぜコンピューターは2進数を使うのか
コンピューターが2進数を使う理由は、電気回路の「オン(1)」と「オフ(0)」という二状態に対応しているからです。
トランジスタという電子素子は、電圧が高い(1)か低い(0)かの二状態しか持てません。
この物理的な制約が、コンピューターにおける2進数の採用の直接的な理由です。
8進数や16進数は、2進数を人間が扱いやすいようにグループ化した表記法として使われます。
2進数3桁が8進数1桁に、2進数4桁が16進数1桁にそれぞれ対応するため、変換が容易です。
16進数はメモリアドレスやRGBカラーコードなどで広く使われており、プログラマーにとって最も重要な非10進数表記です。
進数の表記方法と記号
複数の進数を混在させて書く際には、どの進数かを明示する表記法が必要です。
| 進数 | 数学的表記 | プログラミング表記(C言語等) | 例 |
|---|---|---|---|
| 2進数 | (数値)₂または(数値)₂ | 0b1101(Python)/ 0B1101 | 1101₂ = 13₁₀ |
| 8進数 | (数値)₈ | 015(先頭に0) | 15₈ = 13₁₀ |
| 10進数 | (数値)または(数値)₁₀ | 13(そのまま) | 13₁₀ |
| 16進数 | (数値)₁₆ | 0x0D(先頭に0x) | D₁₆ = 13₁₀ |
プログラミングでは、言語によって表記法が異なります。
Pythonでは0b(2進数)、0o(8進数)、0x(16進数)というプレフィックスで区別します。
JavaScriptやCでも同様に0xで16進数を表します。
10進数から他の進数への変換方法
続いては、10進数から2進数・8進数・16進数への具体的な変換方法について確認していきます。
最も基本的な変換方向であり、確実に習得しておくことが重要です。
10進数から2進数への変換(割り算法)
10進数を2進数に変換する最も基本的な方法は「2で繰り返し割り算をする方法」です。
【10進数 → 2進数の変換手順(割り算法)】
例:13₁₀を2進数に変換する
13 ÷ 2 = 6 余り 1 ← 最下位ビット(LSB)
6 ÷ 2 = 3 余り 0
3 ÷ 2 = 1 余り 1
1 ÷ 2 = 0 余り 1 ← 最上位ビット(MSB)
余りを下から読む(MSBからLSBの順):1101
よって 13₁₀ = 1101₂
検証:1×8 + 1×4 + 0×2 + 1×1 = 13 ✓
「余りを下から読む」という点が重要で、最初の余りが最下位ビット(一の位)に対応します。
割り算法は任意のn進数変換に応用でき、n で繰り返し割った余りを下から読むというルールは常に共通です。
商がゼロになったら終了し、そこまでの余りを逆順に並べたものが変換結果です。
10進数から16進数への変換
10進数から16進数への変換も、16で繰り返し割り算をする方法が基本です。
【10進数 → 16進数の変換手順】
例:255₁₀を16進数に変換する
255 ÷ 16 = 15 余り 15(F)← 下位桁
15 ÷ 16 = 0 余り 15(F)← 上位桁
余りを下から読む:FF
よって 255₁₀ = FF₁₆
検証:15×16 + 15×1 = 240 + 15 = 255 ✓
別例:200₁₀ → 200 ÷ 16 = 12 余り 8, 12 ÷ 16 = 0 余り 12(C)
→ C8₁₆ → 検証:12×16 + 8 = 192 + 8 = 200 ✓
余りが10以上の場合は、A(10)・B(11)・C(12)・D(13)・E(14)・F(15)に対応させます。
これが16進数の計算で最も混乱しやすいポイントですので、A〜Fと10〜15の対応を確実に覚えておきましょう。
10進数から8進数への変換
8進数への変換も同じ手順で行います。
【10進数 → 8進数の変換手順】
例:100₁₀を8進数に変換する
100 ÷ 8 = 12 余り 4
12 ÷ 8 = 1 余り 4
1 ÷ 8 = 0 余り 1
余りを下から読む:144
よって 100₁₀ = 144₈
検証:1×64 + 4×8 + 4×1 = 64 + 32 + 4 = 100 ✓
8進数は2進数3桁と対応しているため、2進数が扱いやすくなる場合に使われます。
UNIXやLinuxのファイルパーミッション(chmod 755など)が8進数を使っている代表的な例です。
2進数・8進数・16進数の相互変換
続いては、2進数・8進数・16進数の間の相互変換について確認していきます。
これらの変換は、2進数が基準になっているため非常にスムーズに行えます。
2進数と16進数の変換(4桁ずつグループ化)
2進数と16進数の変換は、2進数を4桁ずつグループ化することで非常に簡単に行えます。
これは16 = 2⁴であるため、2進数4桁がちょうど16進数1桁に対応するからです。
【2進数 → 16進数の変換(4桁グループ法)】
例:10111010₂を16進数に変換する
右から4桁ずつグループ化:1011 | 1010
1011₂ = 11₁₀ = B₁₆
1010₂ = 10₁₀ = A₁₆
よって 10111010₂ = BA₁₆
【16進数 → 2進数の変換】
例:3F₁₆を2進数に変換する
3₁₆ = 0011₂
F₁₆ = 1111₂
よって 3F₁₆ = 00111111₂ = 111111₂(先頭の0は省略可)
2進数4桁と16進数1桁が完全に対応しているため、16進数はプログラミングでのバイト(8ビット)表現に最適であり、FF₁₆ = 11111111₂ = 255₁₀という対応が頻繁に使われます。
2進数と8進数の変換(3桁ずつグループ化)
8 = 2³であるため、2進数3桁が8進数1桁に対応します。
【2進数 → 8進数の変換(3桁グループ法)】
例:10111010₂を8進数に変換する
右から3桁ずつグループ化:10 | 111 | 010
(左端が2桁の場合は先頭に0を補う:010)
010₂ = 2₈
111₂ = 7₈
010₂ = 2₈
よって 10111010₂ = 272₈
【8進数 → 2進数の変換】
例:157₈を2進数に変換する
1₈ = 001₂
5₈ = 101₂
7₈ = 111₂
よって 157₈ = 001101111₂ = 1101111₂
主要な進数変換の対照表
| 10進数 | 2進数 | 8進数 | 16進数 |
|---|---|---|---|
| 0 | 0000 | 0 | 0 |
| 1 | 0001 | 1 | 1 |
| 2 | 0010 | 2 | 2 |
| 4 | 0100 | 4 | 4 |
| 7 | 0111 | 7 | 7 |
| 8 | 1000 | 10 | 8 |
| 10 | 1010 | 12 | A |
| 15 | 1111 | 17 | F |
| 16 | 10000 | 20 | 10 |
| 255 | 11111111 | 377 | FF |
| 256 | 100000000 | 400 | 100 |
この変換表は、2進数・8進数・16進数の対応関係を一目で確認できる非常に有用なツールです。
特に 15₁₀ = 1111₂ = F₁₆、255₁₀ = 11111111₂ = FF₁₆ という対応は、コンピューターサイエンスにおいて最も頻出する変換値として必ず覚えておきましょう。
小数の進数変換
続いては、小数(0以上1未満の数)の進数変換について確認していきます。
整数の変換よりやや複雑ですが、掛け算を繰り返す方法で体系的に求められます。
10進数の小数を2進数に変換する方法
10進数の小数を2進数に変換するには、「2を繰り返し掛け算して整数部分を取り出す」方法を使います。
【10進数小数 → 2進数の変換手順(掛け算法)】
例:0.625₁₀を2進数に変換する
0.625 × 2 = 1.25 → 整数部分 1 ← 最上位ビット
0.25 × 2 = 0.5 → 整数部分 0
0.5 × 2 = 1.0 → 整数部分 1 ← 小数部がゼロになれば終了
整数部分を上から読む:101
よって 0.625₁₀ = 0.101₂
検証:1×(1/2) + 0×(1/4) + 1×(1/8) = 0.5 + 0 + 0.125 = 0.625 ✓
整数の変換では余りを「下から読む」のに対し、小数の変換では整数部分を「上から読む」点が重要な違いです。
10進数の小数がすべて有限桁の2進数に変換できるわけではなく、たとえば0.1₁₀は2進数では無限循環小数になります。これがコンピューターでの浮動小数点誤差の根本原因です。
有名な10進数小数の2進数表現
【代表的な小数の2進数変換例】
0.5₁₀ = 0.1₂(= 1/2)
0.25₁₀ = 0.01₂(= 1/4)
0.125₁₀ = 0.001₂(= 1/8)
0.75₁₀ = 0.11₂(= 1/2 + 1/4)
0.1₁₀ = 0.0001100110011…₂(無限循環)
0.3₁₀ = 0.0100110011…₂(無限循環)
1/2のべき乗(1/2, 1/4, 1/8, 1/16, …)の和で表せる小数のみ有限桁の2進数になります。
0.1 + 0.2 = 0.30000000000000004 という有名な浮動小数点誤差の問題も、0.1と0.2が2進数では無限小数になることが原因です。
プログラミングでお金の計算を行う際に浮動小数点を避け、整数計算や特殊なライブラリを使う理由がここにあります。
小数を含む数の変換
整数部と小数部を持つ数(例:13.625)の変換では、整数部と小数部を別々に変換して合わせます。
【整数+小数の変換例】
13.625₁₀を2進数に変換する
整数部 13₁₀ = 1101₂(割り算法)
小数部 0.625₁₀ = 0.101₂(掛け算法)
合わせる:13.625₁₀ = 1101.101₂
検証:8+4+0+1 + 0.5+0+0.125 = 13 + 0.625 = 13.625 ✓
進数変換の応用と実践的な問題
続いては、進数変換の応用例と実践的な問題について確認していきます。
進数変換は情報処理試験やプログラミングの現場で頻繁に使われる実践的なスキルです。
情報処理試験での頻出問題パターン
基本情報技術者試験などの情報処理試験では、進数変換に関する問題が必ず出題されます。
頻出パターンを整理しておきましょう。
【頻出問題パターン①:2進数の加算】
1011₂ + 1101₂ を計算せよ
解法:
1011 + 1101 = 11000₂
(一の位:1+1=10₂、繰り上がり1、二の位:1+0+1=10₂、繰り上がり1)
10進数で確認:11 + 13 = 24 = 11000₂ ✓
【頻出問題パターン②:16進数の四則演算】
A3₁₆ + 2F₁₆ を計算せよ
解法:10進数変換して計算→ 163 + 47 = 210 = D2₁₆
または直接計算:3+F=3+15=18=12₁₆(2繰り上がり1)、A+2+1=D
答え:D2₁₆
コンピューターでの実用的な進数変換の場面
| 場面 | 使用する進数 | 具体例 |
|---|---|---|
| IPアドレス(IPv4) | 10進数・2進数 | 192.168.1.1 = C0.A8.01.01₁₆ |
| RGBカラーコード | 16進数 | #FF5733 = 赤255, 緑87, 青51 |
| ファイルパーミッション | 8進数・2進数 | chmod 755 = 111 101 101₂ |
| ASCII/Unicode | 16進数・10進数 | ‘A’ = 0x41 = 65₁₀ |
| メモリアドレス | 16進数 | 0x7FFFFFFF(32ビット最大値) |
| ビットマスク | 2進数・16進数 | 0xFF = 11111111₂(下位8ビットのマスク) |
Webデザインで使う #FF5733 のようなカラーコードは、RとGとBそれぞれを16進数2桁で表した6桁の16進数です。
16進数2桁(00〜FF)は0〜255の範囲を表し、これがRGBの各チャンネルの値の範囲(0〜255)と完全に対応しています。
ビット演算と進数変換の関係
プログラミングにおけるビット演算(AND・OR・XOR・シフト演算)は、2進数の理解を前提としています。
【ビット演算と2進数の関係】
AND演算(&):対応するビットが両方1のときのみ1
例:1010₂ & 1100₂ = 1000₂(10 & 12 = 8)
OR演算(|):どちらかのビットが1なら1
例:1010₂ | 1100₂ = 1110₂(10 | 12 = 14)
XOR演算(^):ビットが異なるときのみ1
例:1010₂ ^ 1100₂ = 0110₂(10 ^ 12 = 6)
左シフト(<<):ビットを左にn桁ずらす(2のn乗倍)
例:1₂ << 3 = 1000₂ = 8₁₀
右シフト(>>):ビットを右にn桁ずらす(2のn乗で割る)
例:1000₂ >> 2 = 10₂ = 2₁₀
ビット演算の理解には2進数表現が不可欠であり、進数変換のスキルがプログラミングの効率と理解を直接高めます。
まとめ
本記事では、進数変換の基本的な仕組みから、10進数と2進数・8進数・16進数の相互変換、小数の変換方法、実践的な応用まで幅広く解説してきました。
進数変換の本質は「位取り記数法における基数の違い」であり、10進数から他の進数への変換は「基数で繰り返し割り算した余りを逆から読む」、小数の変換は「基数を繰り返し掛けて整数部を順に読む」という二つの手順で体系的に行えます。
2進数4桁=16進数1桁、2進数3桁=8進数1桁という対応関係を利用すれば、2進数と8進数・16進数の相互変換はグループ化するだけで非常に簡単に行えます。
小数の2進数変換では、0.1のような10進数の単純な小数でも無限循環2進数になる場合があり、これがコンピューターの浮動小数点誤差の根本原因です。
RGBカラーコード・IPアドレス・ファイルパーミッション・メモリアドレスなど、日常的に使うコンピューター技術の多くに進数変換の知識が活きています。
進数変換をしっかりマスターすることで、コンピューターサイエンスとプログラミングへの理解が格段に深まるでしょう。