2進数から10進数への変換
2進数から10進数への変換
このレッスンで分かること
- 2 進数 → 10 進数は「各桁に
2^nの重みを掛けて足す」だけで計算できる- 例として
1101(2 進) は1*8 + 1*4 + 0*2 + 1*1 = 13(10 進) になる- Python なら
int("1101", 2)、JavaScript ならparseInt("1101", 2)で 1 行- このレッスンでは「ホーナー法」で自前実装し、原理から理解する
2進数から10進数への変換 とは
2進数の文字列を10進数の整数に変換する関数を実装し、位取りの仕組みを理解する。本レッスンでは、2進数から10進数への変換 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
コンピュータの世界はすべて 0 と 1 で動いています。電気が流れているかどうかという二択でしかないため、内部のあらゆる情報は 2進数 で表現されます。一方で、私たち人間が普段使っているのは 10進数 です。プログラムを書く以上、この 2 つの世界を行き来できる感覚を持っておくと、後の章で出てくる ビット演算 や メモリ表現 がぐっと身近になります。
本レッスンでは「1101 という 2 進数の文字列を渡されたら、それが 10 進数の 13 だと計算して返す」関数を作ります。やっていることは小学校で習う「桁ごとに重みをかけて足す」のと同じ仕組みです。違いは、重みが 10 ではなく 2 に変わるだけです。
2 進数は「電気が流れているか否か」の表現。10 進数への変換は「桁の重み付き和」を計算するだけ。
位取り記数法のおさらい
10 進数の 253 は、2 * 100 + 5 * 10 + 3 * 1 と分解できます。一の位、十の位、百の位に重み 1、10、100 が割り当てられていて、それぞれは 10^0、10^1、10^2 です。これを 位取り記数法 といいます。
2 進数でも考え方はまったく同じで、重みが 2 の累乗になります。1101 を右から見ると、1 * 1 + 0 * 2 + 1 * 4 + 1 * 8 = 13 です。重みは 2^0、2^1、2^2、2^3 と続きます。一般に、n 桁目の重みは 2^(n-1) であり、桁が 1 つ増えるたびに表現できる範囲は 2 倍に広がります。
4 ビットなら 0000 から 1111 まで、つまり 0 から 15 までの 16 通りを表せます。8 ビットなら 256 通り、16 ビットなら 65536 通り、32 ビットなら約 43 億通りです。「1 バイト = 8 ビット = 256 通り」という事実は、文字コードやカラーコードの議論でも頻繁に登場します。
桁の重みは右端から
2^0、2^1、2^2…。これは 2 進数も 10 進数も同じで、基数だけが違う。
ビジュアルで理解する
ステップ要約 (図と同じ内容を箇条書きで再掲)
1101の各桁を右から bit0, bit1, bit2, bit3 と番号付けする- それぞれに
2^0 = 1、2^1 = 2、2^2 = 4、2^3 = 8の重みを当てる - 桁の値 (0 か 1) と重みを掛ける (
1*8,1*4,0*2,1*1) - すべての結果を足し合わせる (
8 + 4 + 0 + 1 = 13)
変換例の早見表
| 2 進数 | 計算式 | 10 進数 |
|---|---|---|
0001 | 0+0+0+1 | 1 |
0101 | 0+4+0+1 | 5 |
1010 | 8+0+2+0 | 10 |
1101 | 8+4+0+1 | 13 |
1111 | 8+4+2+1 | 15 |
図のように、1101 の各桁が 0 か 1 かを見て、1 のところだけ重みを足し合わせれば 10 進数になります。0 の桁は無視しても結果は変わりません。これは 10 進数で言えば、203 の 0 を計算しても 0 にしかならないのと同じ感覚です。
Python での実装
Python には組み込み関数 int(s, 2) が存在し、これだけで変換できます。しかし、変換の 原理 を理解するために、ここでは自前で実装します。
Python
def binToDec(binary):
result = 0
for ch in binary:
result = result * 2 + int(ch)
return resultポイントは result = result * 2 + int(ch) の部分です。左から右へ 1 文字ずつ読むたびに、これまでの result を 2 倍してから新しい桁を足す、という処理を繰り返します。これは数学的には ホーナー法 と呼ばれる手法で、桁数が大きくても効率よく計算できます。1101 を左から処理すると、0 →(0×2+1=)1 →(1×2+1=)3 →(3×2+0=)6 →(6×2+1=)13 のように、毎回 ×2 してから桁を足すだけです。
JavaScript での実装
JavaScript
function binToDec(binary) {
let result = 0;
for (const ch of binary) {
result = result * 2 + Number(ch);
}
return result;
}JavaScript も同じロジックで書けます。parseInt(binary, 2) を使えば 1 行ですが、ここでは原理を追います。Number(ch) で文字を数値に変換しています。+ch という単項プラスでも同じ効果が得られます。
計算量の話
このアルゴリズムは入力文字列の長さを n とすると O(n) です。各桁を 1 回ずつ見るだけなので、これより速くするのは難しいでしょう。int(s, 2) のような組み込み関数も内部的には同じことをやっています。
自前実装と組み込み関数で 計算量は同じ。違いは「学習目的か実務目的か」だけ。
よくある間違い
1 つ目は「右から左に処理しようとして混乱する」ケースです。左から処理して * 2 を繰り返すだけで自然に位が上がるので、わざわざ reverse する必要はありません。2 つ目は 空文字列 が来たときの扱いを忘れることです。空文字なら結果は 0 になるよう、result の初期値で吸収しておきましょう。3 つ目は int(ch) を忘れて文字列の連結になってしまうケースです。"1" + "1" は 2 ではなく "11" になります。
やってみよう
1011を手計算で 10 進数にしてみる。11になるか確認する- 32 ビットすべてが
1の文字列"11111111111111111111111111111111"を入れると何が返るか試す。4294967295になります - 関数を逆方向 (10 進数 → 2 進数) にも書いてみる。次のレッスンで扱います
parseInt("1101", 2)やint("1101", 2)を試して、自前実装と結果が一致することを確認する
2 進数の理解は ビット演算 や メモリ表現 の土台になります。ここでつまずかないようにしっかり手を動かしましょう。
よくある質問
Q. 進数変換はなぜプログラミングで必要なのですか?
A. コンピュータは内部で 2 進数を扱うため、ビット演算やメモリ操作で 2 進・16 進の理解が必須です。色コード(#FF8800)、ファイル権限(0755)、IP アドレスのサブネット計算など、実務でも進数変換に触れる機会は多くあります。
Q. 10 進数を 2 進数に変換するアルゴリズムは?
A. 数を 2 で割り続け、余りを下から並べると 2 進表現になります。例えば 13 → 6 余 1 → 3 余 0 → 1 余 1 → 0 余 1 で 1101 です。多くの言語は bin() / Integer.toBinaryString() などの組み込みがあるため、それを使うのが安全です。
Q. Base64 はなぜ 4/3 倍に膨らむのですか?
A. 3 バイト(24 ビット)を 4 文字(各 6 ビット)に変換するため、データ量が 4/3 倍になります。8 ビット境界の任意バイト列を ASCII 印字可能文字だけで安全に運ぶための仕組みで、メール添付や URL 内のバイナリ埋め込みで使われます。
次のレッスン
次は 10進数から2進数への変換 に進みましょう。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 2進数から10進数 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 2進数から10進数 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- binary は '0' と '1' のみからなる文字列であると仮定して良い
- 組み込みの基数変換関数 (int(s, 2) や parseInt(s, 2)) は使わず、桁ごとに計算する
- 戻り値は 10 進数の整数 (int) であること
入出力例
test-cases.txt
binToDec("1101") → 13
binToDec("0") → 0
binToDec("1") → 1
binToDec("1010") → 10
binToDec("11111111") → 255
binToDec("100000") → 32