レッスン110
2進数入門⌗
n個の数字を使って数を表現する方法をn進数と言います。 私達が通常使っているのは0から9までの数字を使った10進数です。 でも、コンピュータの世界では0と1だけを使った2進数が基本となります。 なぜコンピュータは2進数を使うのでしょうか?
コンピュータは電気信号を使って動作しており、電気の「ON(1)」と「OFF(0)」の状態を基本として情報を処理します。 そのため、2進数がコンピュータにとって最も自然な数の表示方法なのです。
n進法の基本概念⌗
n進数の基本ルール⌗
- 10進数: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 (10個の数字)
- 2進数: 0, 1 (2個の数字)
- 8進数: 0, 1, 2, 3, 4, 5, 6, 7 (8個の数字)
- 16進数: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F (16個の数字)
16進数では、10以上の値をAからFのアルファベットで表現します。
位取り記数法の理解⌗
すべての進数は「位取り記数法」という原理に基づいています。 これは、数字の位置によって、その数字が表す値が変わるという仕組みです。
10進数の例⌗
1234 = 1*10^3 + 2*10^2 + 3*10^1 + 4*10^0
= 1*1000 + 2*100 + 3*10 + 4*1
= 1000 + 200 + 30 + 4
= 1234
この原理は他の進法でも同じように適用されます。
2進法の基本概念⌗
2進法の仕組み⌗
2進法は、0と1の2つの数字だけを使って数を表現します。 位取り記数法により、右から左に向かって2の0乗、2の1乗、2の2乗…という重みを持ちます。
2進数の例⌗
1011 = 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0
= 1*8 + 0*4 + 1*2 + 1*1
= 8 + 0 + 2 + 1
= 11
なお、2進数の「1011」は10進数の「1011」と区別するため、例えばPythonでは先頭に「0b」を付けて0b1011のように表示します。
2進数の数え方⌗
2進数では、0から始まって以下のように数を数えます。
10進数 2進数
0 0
1 1
2 10 (1*2^1 + 0*2^0)
3 11 (1*2^1 + 1*2^0)
4 100 (1*2^2 + 0*2^1 + 0*2^0)
5 101 (1*2^2 + 0*2^1 + 1*2^0)
6 110 (1*2^2 + 1*2^1 + 0*2^0)
7 111 (1*2^2 + 1*2^1 + 1*2^0)
8 1000 (1*2^3 + 0*2^2 + 0*2^1 + 0*2^0)
2進法では、各桁で「繰り上がり」の発生するタイミングが10進法とは異なります。
10進法の2を表す際、0→1の次は、もう使える数字がないので0b10になります。
ビットとの関係⌗
ビットとは⌗
ビット(bit)とは、2進数の1桁を表す単位です。1ビットは0または1の値を持ちます。
2進数: 1011
ビット: 4ビット(4桁)
バイトとの関係⌗
「1バイト = 8ビット」という関係があります。 これは、コンピュータが情報を処理する際の基本単位となっています。
8ビットで表現できる値の範囲⌗
最小値: 00000000 = 0
最大値: 11111111 = 255
2進数の簡単な覚え方⌗
パターン1 : 2の累乗(2を何回も掛け合わせる値)を暗記する⌗
まず2の累乗(2を何回も掛け合わせる値)を覚えることから始めましょう。 これは2進数変換の基礎となります。
2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
2^8 = 256
覚え方のコツ⌗
2の累乗は、前の値を2倍していくだけです。
1 → 2 → 4 → 8 → 16 → 32 → 64 → 128 → 256 …
この数列を覚えることで、2進数の各桁の重みが分かります。
パターン2 : 規則性を見つける⌗
2進数には規則性があります。
| 10進数 | 2進数(3桁で表示) | 3桁目(4の位) | 2桁目(2の位) | 1桁目(1の位) |
|---|---|---|---|---|
| 0 | 000 | 0 | 0 | 0 |
| 1 | 001 | 0 | 0 | 1 |
| 2 | 010 | 0 | 1 | 0 |
| 3 | 011 | 0 | 1 | 1 |
| 4 | 100 | 1 | 0 | 0 |
| 5 | 101 | 1 | 0 | 1 |
| 6 | 110 | 1 | 1 | 0 |
| 7 | 111 | 1 | 1 | 1 |
各桁の規則性⌗
- 1桁目(右端):1つおきに0と1が交互に現れる
- 2桁目:2つずつ0が続き、2つずつ1が続く
- 3桁目:4つずつ0が続き、4つずつ1が続く
1桁目(1の位): 0, 1, 0, 1, 0, 1, 0, 1...(1つおきに変化)
2桁目(2の位): 0, 0, 1, 1, 0, 0, 1, 1...(2つおきに変化)
3桁目(4の位): 0, 0, 0, 0, 1, 1, 1, 1,..(4つおきに変化)
この法則は、「n桁目は2^(n-1)個おきに変化する」という法則にまとめりことができます。 この法則性を理解することで、2進数の並びを覚えやすくなります。
10進数から2進数への変換⌗
割り算を使った変換方法⌗
最も基本的で確実な方法は、10進数を2で割り続ける方法です。
ステップバイステップの手順⌗
- 10進数を2で割る
- 商(割った答え)と余り(0か1)を記録する
- 商(割った答え)が0になるまで2.を繰り返す
- 余りを下から上に読む
例:13を2進数に変換⌗
13 ÷ 2 = 6 余り 1
6 ÷ 2 = 3 余り 0
3 ÷ 2 = 1 余り 1
1 ÷ 2 = 0 余り 1
余りを下から読む:1101
2の累乗を使った変換方法⌗
2の累乗を暗記している場合、より直感的な方法があります。
例:13を2進数に変換⌗
- 13以下の2の累乗数を探す 1, 2, 4, 8, 16…の中で、13以下の累乗数は「1, 2, 4, 8」
- 13以下の累乗数のうち一番大きい8を13から引く → 残り5
- 次に大きい4を残り5から引く → 残り1
- 次に大きい2は残り1より大きいので、2は引かない
- 次に大きい1を残り1から引く → 残り0
残りが0になったので、引いた累乗値で 8 + 4 + 1 = 13 = 2^3 + 2^2 + 2^0 と表せる。
13を作るために引いた2の累乗の位置に「1」、引かなかった2の累乗の位置に「0」を入れます。
| 2の累乗 | 8(2^3) | 4(2^2) | 2(2^1) | 2(2^0) |
|---|---|---|---|---|
| 引いた? | yes | yes | no | yes |
| 2進数 | 1 | 1 | 0 | 1 |
したがって、13の2進数表現は1101になります。
16進数⌗
コンピュータは2進数が基本ですが、2進数は桁数が多くて表示するのが大変です。 そこで、一般的には、2の累乗数である8や16を使って8進数や16進数で2進数の値を表現するのが一般的です。 ここでは、最も一般的な16進数について説明します。
2進数と16進数の関係⌗
2進数の値を4桁ずつ区切って、各4桁の値を0から15(16進数では0からF)で表現したものが16進数になります。
11011010(10進数で218) → |1101|1010| → |D|A| → DA(16進数)
同様に、16進数の値は桁ごとに4桁の2進数に変換すれば、2進数になります。
DA(10進数で218) → |D|A| → |1101|1010| → 11011010(2進数)
このように、2進数と16進数は簡単に変換できるので、コンピュータの世界では2進数の代わりに16進数で表現することが一般的です。 なお、8進数も同様に3桁区切りで簡単に変換できるので、16進数ほど一般的ではありませんが、使われています。
16進数の基本⌗
16進数は0〜9とA〜Fの16個の文字を使います。 参考までに、8進法と2進法との対応も記載しました。
10進数 16進数 8進数 2進数
0 0 0 0
1 1 1 1
2 2 2 01
3 3 3 11
4 4 4 100
5 5 5 101
6 6 6 110
7 7 7 111
8 8 10 1000
9 9 11 1001
10 A 12 1010
11 B 13 1011
12 C 14 1100
13 D 15 1101
14 E 16 1110
15 F 17 1111
16の累乗を暗記する⌗
16^0 = 1
16^1 = 16
16^2 = 246
16^3 = 4096
10進法から16進法への変換⌗
割り算を使った変換⌗
例:255を16進数に変換⌗
255 ÷ 16 = 15 余り 15
15 ÷ 16 = 0 余り 15
余り15 = F
余り15 = F
結果: FF
2進数経由の変換⌗
先程説明した2進数と16進数の関係を利用します。
例:255を16進数に変換⌗
-
10進数を2進数に変換
255 = 11111111
-
4桁ずつ区切る(右から)
11111111 = |1111|1111|
-
区切った4桁を16進数に変換
1111 = F 1111 = F
-
結果
FF
2進数と16進数の対応は、先程の対応表を参照してください。
16進数から10進数への変換⌗
基本的な考え方⌗
16進数から10進数への変換も、位取り記数法を使います。 16進数の各桁に16の累乗数をかけて、それらを足し合わせます。
16進数の文字を数値に変換⌗
16進法で10〜15の値にA〜Fのアルファベットを使われることを忘れずに。
A = 10 B = 11 C = 12 D = 13 E = 14 F = 15
変換の手順⌗
- 16の累乗を実際の数値に置き換え
- 各項を計算
- 合計して10進数を得る
例:16進数のABを10進数に変換⌗
16進数:AB
まず文字を数値に変換
A = 10, B = 11
各桁に16の累乗数をかけて計算
10*16^1 + 11*16^0
= 10*16 + 11*1
= 160 + 11
= 171
例:16進数のFF00を10進数に変換⌗
16進数:FF00
まず文字を数値に変換
F = 15, F = 15, 0 = 0, 0 = 0
各桁に16の累乗数をかけて計算
15*16^3 + 15*16^2 + 0*16^1 + 0*16^0
= 15*4096 + 15*256 + 0*16 + 0*1 # 16の累乗数を実際の数値に置き換え
= 61440+ 3840 + 0 + 0 # 各項を計算
= 65200 # 合計して10進数を得る
よくある間違いと注意点⌗
間違い1:進数の表記を混同する⌗
☓誤:10進数の10を2進数で「10」と書く
◯正:10進数の10は2進数で「1010」
☓誤:2進数の10を10進数の10と読む
◯正:2進数の10は10進数の2
間違い2:桁の重みを間違える⌗
☓誤:2進数の右から1桁目を2^1とする
◯正:2進数の右から1桁目は2^0(=1)
2進数の正しい桁の重み
位置: 4桁目 3桁目 2桁目 1桁目
重み: 2^3 2^2 2^1 2^0
値: 8 4 2 1
間違い3:16進数の文字を誤解する⌗
☓誤:16進数のAを10進数の「11」と誤解
◯正:16進数のAは10進数の「10」
16進数の対応
A = 10, B = 11, C = 12, D = 13, E = 14, F = 15
KB(キロバイト)、MB(メガバイト)、GB(ギガバイト)、TB(テラバイト)とは⌗
コンピュータのメモリの大きさなどでよく、KB、MB、GB、TBというのを目にします。 キロ(K)とは、1000倍のことで、1000mのことを1km、1000gのことを1kgといいます。 キロ(k)の1000倍がメガ(M)、メガの1000倍がギガ(G)、ギガの1000倍がテラ(T)です。
ただし、コンピュータの世界では2進数が基本なので、コンピュータの世界でのキロ(K)は1000倍ではなく、2^10(2の10乗)の1024倍になります。 したがって、1KBは1000Bではなく、1KB = 1024Bになります。同様に1MB = 1024KB、1GB = 1024MB、1TB = 1024GBとなります。
1TB = 1024GB = 1048576MB = 1073741824KB = 109951162776B = 8796093022208bit となり、1TBのメモリには8796093022208個のデータ(0か1)が格納できることになります。
課題⌗
課題1⌗
Pythonで10進数を2進数に変換するプログラムを作ってください。数値を入力して、2進数の値を0か1の文字列にして、print関数で出力してください。 Pythonには10進数を2進数に変換する便利な関数が用意されていますが、それを使わず、「割り算を使った変換方法」か「の累乗を使った変換方法」でプログラムを作成してください。
回答例
def dec2bin(x):
s = ""
while True:
s = ("0" if x % 2 == 0 else "1") + s
x //= 2
if x == 0:
break
return s
x = int(input())
print(dec2bin(x))
課題2⌗
Pythonで2進数の文字列を入力して、10進数の数値に変換してprint関数で出力してください。 Pythonには2進数を10進数に変換する便利な関数が用意されていますが、それを使わず、「位取り記数法」でプログラムを作成してください。
回答例
def bin2dec(b):
s = reversed(b)
x = 0
i = 1
for c in s:
x += int(c) * i
i *= 2
return x
b = input()
print(bin2dec(b))
課題3⌗
Pythonで10進法を16進法に変換するプログラムを作ってください。数値を入力して、16進数の値を0〜Fを使用したの文字列にして、print関数で出力してください。 また、Pythonで16進数の文字列を入力して、10進数の数値に変換してprint関数で出力してください。 いずれもPythonで用意された関数は使わないで「割り算を使った変換」や「位取り記数法」でプログラムを作成するか、先程作った2進数・10進数変換プログラムを経由したプログラムを作成してください。
回答例
def dec2hex(x):
s = ""
while True:
s = "0123456789ABCDEF"[x%16] + s
x //= 16
if x == 0:
break
return s
x = int(input())
print(dec2hex(x))
def hex2dec(b):
s = reversed(b)
x = 0
i = 1
for c in s:
x += "0123456789ABCDEF".index(c) * i
i *= 16
return x
b = input()
print(hex2dec(b))