基数変換ガイド:2進数・16進数・8進数をわかりやすく解説
#1A2B3C のようなカラーコードや chmod 755 のようなUnixパーミッションを見て、「この数字はどこから来るんだろう」と思ったことがあるなら、あなただけではありません。基数(ベース)はほとんどの開発者が毎日無意識に使っている基礎概念ですが、いざ基数間の変換が必要になった瞬間に戸惑うものです。
このガイドでは、プログラミングで重要な数値システム、基数間の変換方法、そして各システムが実際に使われる場面を解説します。
「基数」とは何を意味するのか?
私たちが10進数(基数10)で数えるのは、指が10本あるからです。各桁は10のべき乗を表しています:
4 2 7
| | |
| | └── 7 × 10⁰ = 7
| └────── 2 × 10¹ = 20
└────────── 4 × 10² = 400
───
合計 = 427
これが位取り記数法です。「基数」(radixとも呼ばれる)は、そのシステムで使える固有の数字の数と、各桁の乗数を示します。基数10では0〜9の数字を使い、基数2では0と1、基数16では0〜9とA〜Fを使います。
この概念はすべての基数で同じです — 変わるのは使える記号の数と各桁の乗数だけです。
豆知識:古代バビロニア人は60進法(六十進法)を使っていました。1分が60秒、円が360度なのはそのためです。
2進数(基数2):ハードウェアの言語
なぜコンピュータは2進数を使うのか
コンピュータはトランジスタで動作しており、トランジスタにはオンとオフの2つの安定した状態があります。これは1と0に完璧に対応します。理論的には3進数のコンピュータも作れますが、3つの電圧レベルを区別するのは2つを区別するより難しく、エラーも起きやすくなります。2進数が選ばれているのは、シンプルで堅牢だからです。
2進数の読み方
2進数も10進数と同じ仕組みですが、各桁が2のべき乗を表します:
1 0 1 1 0 1
| | | | | |
| | | | | └── 1 × 2⁰ = 1
| | | | └────── 0 × 2¹ = 0
| | | └────────── 1 × 2² = 4
| | └────────────── 1 × 2³ = 8
| └────────────────── 0 × 2⁴ = 0
└────────────────────── 1 × 2⁵ = 32
──
合計 = 45
つまり、2進数の 101101 は10進数の45です。右から左へ読み、各桁の位の値は2倍になっていきます:1, 2, 4, 8, 16, 32, 64, 128...
ビット、ニブル、バイト
- ビット(Bit): 1桁の2進数(0または1)
- ニブル(Nibble): 4ビット(16進数1桁に対応、0〜15の値)
- バイト(Byte): 8ビット(0〜255の値)
- キロバイト(Kilobyte): 1,024バイト(2¹⁰)
1バイトで256通りの値を表現できます。ASCII文字が1バイトに収まり、RGB色チャネルが0〜255の範囲なのはこのためです。
2進数の基本的な演算
2進数の加算は10進数と同じルールに従いますが、10ではなく2で繰り上がります:
1 0 1 1 (10進数で 11)
+ 0 1 1 0 (10進数で 6)
─────────
1 0 0 0 1 (10進数で 17)
2進数では 1 + 1 = 10 になります(10進数で 9 + 1 = 10 になるのと同じ)。0を書いて1を繰り上げます。
8進数(基数8):レガシーシステム
簡単な歴史
8進数は1960〜70年代にPDP-8のようなマシンで広く使われていました。これらのマシンは12ビットワードを採用しており、3ビットずつ4つのグループにきれいに分割できました。8進数の各桁は正確に3桁の2進数に対応するため、便利な略記法として機能していました。
8進数が今でも使われる場面
今日もっともよく目にするのはUnixファイルパーミッションです。chmod 755 script.sh と入力するとき、各桁は読み取り(4)、書き込み(2)、実行(1)の権限を表す8進数です:
7 = 4 + 2 + 1 = rwx (所有者: 読み取り, 書き込み, 実行)
5 = 4 + 0 + 1 = r-x (グループ: 読み取り, 実行)
5 = 4 + 0 + 1 = r-x (その他: 読み取り, 実行)
プログラミングでは8進数リテラルに 0o プレフィックスを使います(C言語では先頭の 0 だけで8進数になりますが、これが多くのバグの原因となっています):
const permissions = 0o755; // 493 in decimal
console.log(permissions.toString(8)); // "755"
JavaScriptやPythonでは注意が必要です:0755 のように先頭にゼロを付けると、一部のコンテキストでは8進数として解釈されることがあります。曖昧さを避けるため、常に明示的な 0o プレフィックスを使いましょう。
16進数(基数16):開発者のお気に入り
16進数が存在する理由
16進数は実用的な問題を解決します。2進数はすぐに桁数が長くなるのです。10進数の255は2進数では 11111111 と8桁になりますが、16進数なら FF のたった2桁です。16進数の各桁は正確に4桁の2進数(1ニブル)に対応するため、変換が簡単で数値もコンパクトに保てます。
16進数では0〜9の数字に加えてA〜Fの文字を使います:
| Decimal | Binary | Hex |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 15 | 1111 | F |
16進数の実際の使用例
Webカラーは16進数のもっとも目に見える用途です。#FF5733 は以下のように分解されます:
#FF5733
││││││
││││└┘── Blue: 0x33 = 51
││└┘──── Green: 0x57 = 87
└┘────── Red: 0xFF = 255
メモリアドレスはデバッガで16進数で表示されます:0x7FFF5FBFFA10 は10進数の 140,734,799,804,944 よりはるかに読みやすいです。
MACアドレスはコロンで区切られた16進数のペアで表されます:A4:83:E7:2B:00:1F
CSSでの色指定: rgba(255, 87, 51, 1.0) と #FF5733 は同じ色を表しますが、16進数のほうがコンパクトです。
基数間の変換
10進数から2進数へ
2で繰り返し割り、余りを下から上へ読みます:
45 ÷ 2 = 22 remainder 1 ↑
22 ÷ 2 = 11 remainder 0 │
11 ÷ 2 = 5 remainder 1 │ 下から上へ読む:
5 ÷ 2 = 2 remainder 1 │ 101101
2 ÷ 2 = 1 remainder 0 │
1 ÷ 2 = 0 remainder 1 │
結果:10進数の45 = 2進数の 101101
10進数から16進数へ
同じ方法ですが、16で割ります:
427 ÷ 16 = 26 remainder 11 (B) ↑
26 ÷ 16 = 1 remainder 10 (A) │ 下から上へ読む: 1AB
1 ÷ 16 = 0 remainder 1 │
結果:10進数の427 = 16進数の 1AB
2進数から16進数へ(もっとも簡単な変換)
2進数を右から4桁ずつグループに分け、各グループを変換します:
Binary: 10 1101
Padded: 0010 1101
Groups: 2 D
Result: 0x2D
検算:0x2D = 2×16 + 13 = 45 ✓
16進数から2進数へ
逆の手順です。各16進数の桁を4桁の2進数に展開します:
Hex: F A 3
Binary: 1111 1010 0011
Result: 111110100011
ヒント:0〜Fの2進数パターンを暗記しましょう(全部で16個だけです)。これを覚えれば、16進数↔2進数の変換が頭の中で瞬時にできるようになります。まずは2のべき乗から始めましょう:1=0001, 2=0010, 4=0100, 8=1000。
プログラミング言語での基数表記
主要な言語にはすべて、異なる基数で数値を記述する構文があります:
// JavaScript
const binary = 0b101101; // 45
const octal = 0o55; // 45
const hex = 0x2D; // 45
const decimal = 45; // 45
(45).toString(2); // "101101"
(45).toString(8); // "55"
(45).toString(16); // "2d"
parseInt("101101", 2); // 45
parseInt("55", 8); // 45
parseInt("2D", 16); // 45
# Python
binary = 0b101101 # 45
octal = 0o55 # 45
hexval = 0x2D # 45
bin(45) # '0b101101'
oct(45) # '0o55'
hex(45) # '0x2d'
int("101101", 2) # 45
int("55", 8) # 45
int("2D", 16) # 45
// C / C++
int binary = 0b101101; // 45 (C23 / GCC extension)
int octal = 055; // 45 (leading zero = octal!)
int hex = 0x2D; // 45
C言語の注意点:先頭の 0 は8進数を意味します。int x = 010; と書くと、10ではなく8が得られます。
実践的なユースケース
ビット演算とフラグ
const READ = 0x01; // 0001
const WRITE = 0x02; // 0010
const EXECUTE = 0x04; // 0100
const ADMIN = 0x08; // 1000
let permissions = READ | WRITE; // 0x03 = 0011
if (permissions & EXECUTE) {
// check if execute bit is set
}
デバッグとメモリ検査
セグメンテーション違反のアドレスに 0xDEADBEEF が表示されたり、メモリを 0xCAFEBABE で初期化したりするのを見たことがあるかもしれません。これらはメモリダンプで見つけやすいように意図的に選ばれた16進数の定数です。Javaクラスファイルはマジックナンバー 0xCAFEBABE で始まります。
ネットワークプロトコル
IPv6アドレスは16進数表記を使います:2001:0db8:85a3:0000:0000:8a2e:0370:7334。MACアドレス、USBベンダーID、Bluetooth UUIDもすべて16進数を使用しています。
実際に試してみましょう
手計算は不要です。基数変換ツールを使えば、任意の基数間の変換が瞬時にできます。すべてブラウザ上で処理されるため、サーバーにデータが送信されることはありません。
特に以下のような場面で便利です:
- 16進数のメモリダンプを10進数に変換してデバッグする
- Unixパーミッションを2進数・8進数で計算する
- カラーコードを16進数とRGB値の間で検証する
- 2のべき乗でない基数間の変換を行う
関連リソース
- Base64エンコーディング解説 — Base64はバイナリをテキストにエンコードするための異なるアプローチを使います
- ハッシュアルゴリズム比較 — ハッシュ出力は通常16進数で表示されます
- 基数変換ツール — ブラウザ上で任意の基数間を瞬時に変換
🛠️ 今すぐ試す: 基数変換ツール — 2進数、8進数、10進数、16進数、最大36進数まで任意の基数間で変換。100%クライアントサイド処理、完全無料。