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で割り続ける方法です。

ステップバイステップの手順

  1. 10進数を2で割る
  2. 商(割った答え)と余り(0か1)を記録する
  3. 商(割った答え)が0になるまで2.を繰り返す
  4. 余りを下から上に読む

例:13を2進数に変換

13 ÷ 2	= 6 余り 1
6 ÷ 2	= 3 余り 0
3 ÷ 2	= 1 余り 1
1 ÷ 2	= 0 余り 1

余りを下から読む:1101

2の累乗を使った変換方法

2の累乗を暗記している場合、より直感的な方法があります。

例:13を2進数に変換

  1. 13以下の2の累乗数を探す 1, 2, 4, 8, 16…の中で、13以下の累乗数は「1, 2, 4, 8」
  2. 13以下の累乗数のうち一番大きい8を13から引く → 残り5
  3. 次に大きい4を残り5から引く → 残り1
  4. 次に大きい2は残り1より大きいので、2は引かない
  5. 次に大きい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進数に変換

  1. 10進数を2進数に変換

    255 = 11111111

  2. 4桁ずつ区切る(右から)

    11111111 = |1111|1111|

  3. 区切った4桁を16進数に変換

    1111 = F 1111 = F

  4. 結果

    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

変換の手順

  1. 16の累乗を実際の数値に置き換え
  2. 各項を計算
  3. 合計して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))