
C言語基礎|基数変換
「2進数」「8進数」「16進数」は、コンピュータの世界でしょっちゅう出てきます。
でも人間はふだん 10進数で考えるので、基数変換(別の進数へ変換すること)ができると一気に理解がラクになります。
ここでは、
- 2進数・8進数・16進数 → 10進数(重みで足し算)
- 10進数 → 2進数・8進数・16進数(割り算と剰余)
という「2つの王道パターン」を、表や図でしっかり整理していきますね。

基数変換で押さえる2つの基本ルール
基数変換の基本戦略
| 変換方向 | 基本アイデア | キーワード |
|---|---|---|
| n進数 → 10進数 | 各桁に重み(nのべき乗)をかけて足す | 重み、べき乗 |
| 10進数 → n進数 | nで割って剰余を集め、逆順に並べる | 商と剰余、逆順 |
この表は「どっち向きの変換をしているか」で、手順がガラッと変わるのがポイントです。
n進数 → 10進数の変換(重みで足し算)
10進数の各桁が 10⁰, 10¹, 10²… の重みを持つのと同じで、
n進数なら n⁰, n¹, n²… の重みを持ちます。
図:重みの考え方(例:n進数)
桁: 上位 ……………………………… 下位
重み: n3 n2 n1 n0
例1:2進数 101 を 10進数へ
- 101 = 1×2² + 0×2¹ + 1×2⁰
- = 1×4 + 0×2 + 1×1
- = 5
例2:8進数 123 を 10進数へ
- 123 = 1×8² + 2×8¹ + 3×8⁰
- = 1×64 + 2×8 + 3×1
- = 83
例3:16進数 1FD を 10進数へ
16進数は A〜F が登場します。ここが最初の山場!
16進の文字と値
| 文字 | 値 |
|---|---|
| A | 10 |
| B | 11 |
| C | 12 |
| D | 13 |
| E | 14 |
| F | 15 |
- 1FD = 1×16² + 15×16¹ + 13×16⁰
- = 1×256 + 15×16 + 13×1
- = 256 + 240 + 13
- = 509
10進数 → n進数の変換(割り算と剰余)
逆向きの変換は「割り算」です。
nで割った剰余が最下位桁になります。商をさらに割って…を繰り返し、剰余を逆順に並べます。
図:剰余が下の桁になるイメージ
10進数を n で割る
剰余 → いちばん下の桁
商 → 残りをさらに変換する対象
最後に剰余を逆順に並べる

例:10進数 45 を 2進数へ
45 を 2 で割り続けます。
割り算と剰余の記録(45 → 2進数)
| 手順 | 商 | 剰余 |
|---|---|---|
| 45 ÷ 2 | 22 | 1 |
| 22 ÷ 2 | 11 | 0 |
| 11 ÷ 2 | 5 | 1 |
| 5 ÷ 2 | 2 | 1 |
| 2 ÷ 2 | 1 | 0 |
| 1 ÷ 2 | 0 | 1 |
剰余を下から逆に読む → 101101
つまり、45(10) = 101101(2)
変換手順をC言語で確かめよう
ここでは「入力した10進数を、指定した基数(2〜16)に変換して表示する」プログラムにします。
プロジェクト名:chap7-3-1 ソースファイル名:chap7-3-1.c
Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。
// 10進数を指定した基数(2〜16)に変換して表示する
#include <stdio.h>
void print_base(unsigned int value, unsigned int base)
{
char buf[33]; // 2進数でも32ビット分 + 終端
const char digits[] = "0123456789ABCDEF";
int idx = 0;
if (base < 2 || base > 16) {
puts("基数は2〜16で指定してください。");
return;
}
// value が 0 のときは特別扱い(ループが1回も回らないため)
if (value == 0) {
puts("変換結果: 0");
return;
}
// 剰余を順に buf に詰める(下位桁から溜まる)
while (value > 0) {
unsigned int r = value % base;
buf[idx++] = digits[r];
value /= base;
}
// buf は逆順に入っているので、後ろから表示する
printf("変換結果: ");
for (int i = idx - 1; i >= 0; i--) {
putchar(buf[i]);
}
putchar('\n');
}
int main(void)
{
unsigned int n, base;
puts("10進数を好きな基数に変換してみましょう。");
printf("10進数(0以上): ");
scanf("%u", &n);
printf("基数(2〜16): ");
scanf("%u", &base);
print_base(n, base);
return 0;
}このプログラムに出てくる命令の書式と役割
printf
- 書式:printf(書式文字列, 値, ...);
- 役割:書式付きで表示する(案内や結果表示)
puts
- 書式:puts(文字列);
- 役割:文字列を表示して改行する(説明文に便利)
scanf
- 書式:scanf(書式文字列, 変数のアドレス);
- 役割:キーボード入力を読み取る
- %u は unsigned int 用
- &n のように変数のアドレスを渡す
putchar
- 書式:putchar(文字);
- 役割:文字を1文字だけ出力する(変換結果を1桁ずつ出すのに便利)
% と /
- value % base
役割:剰余(その基数の最下位桁) - value /= base
役割:商に更新(右に1桁ずらすイメージ)
表と図でプログラムの動きを説明する(何が起きてる?)
whileループでやっていること
| 処理 | 目的 | 例(value=45, base=2) |
|---|---|---|
| r = value % base | 最下位桁を取り出す | 45 % 2 → 1 |
| buf に r を保存 | 下位桁から溜める | buf に 1 |
| value /= base | 次の桁へ進む | 45 / 2 → 22 |
buf に入る順番(逆順になる理由)
剰余(下位桁)から順に保存される
例:45 を 2進数へ
buf: [1][0][1][1][0][1] ← この順で入る
表示: 101101 ← 逆から読む
この「逆順になる」は基数変換の鉄板ポイントなので、覚えておくと強いです。
