コンピュータは 2 進数を基本としている
コンピュータが 2 進数で動いている、ということはどこかで聞いたことがあると思います。そもそも 10 進数とは
なぜ 2 進数を使うのでしょうか。
多くの人が馴染んでいる 10 進数でないのはなぜでしょう。
3 進数や 4 進数でも良いと思いますが、そうなっていないのはなぜなのでしょう。
ここでは、2 進数を使った整数演算の利便性について説明します。
想像しやすい数で説明すると、10 進数というものがあります。10 進数の補数
これは、手に指が 10 本あることが由来です。
よく「指折り数えて待っていた」という言い方がありますが、実際に両手の指を折り曲げて数を数えることを表現しています。
もし手のひらに指が 20 本あったら、20 進数が一般的な数え方になっていたことでしょう。
10 進数では数を 0,1,2,··,8,9 と、10 種類の字を使って表します。
0 に 1 を加えると 1、
1 に 1 を加えると 2、
という具合に変化していく概念です。
9 に 1 を加えると 10 となり、桁数が増えます。
数字の種類が 10 種類あり、最後の数字に 1 を加えるとひとつ桁数が増えることを「桁上がりする」と言い、これを 10 進数と呼びます。
この文 (↑) の「10」をアルファベットの「n」に言い換えると、こうなります(↓)。
数字の種類が n 種類あり、最後の数字に 1 を加えるとひとつ桁数が増えることを「桁上がりする」と言い、これを n 進数と呼びます。
つまり、n 進数のうち、普段から慣れている (学校で教わる) 数え方が 10 進数なだけで、
数字の種類さえ用意すればどんな n 進数でも作れるということを意味しています。
補数とは、減数 (引く数) が与えられたときの、最大の数に足りない数のことです。(文章にすると分かりにくくなりますが、やりたいことは単純です)補数の使い方
補数には「減基数の補数」と「基数の補数」という 2 種類があります。
です。
減基数の補数は、 「(n 進数 m 桁の最大値) - 引く数」。 基数の補数は、 「(n 進数 m 桁の最大値) - 引く数 + 1」。
例えば、10 進数 2 桁で減数 -4 が与えられたとき、最大の数は 99 なので、
となります。
減基数の補数は 95。 → 99 - 4 基数の補数は 96。 → 99 - 4 + 1
このとき、各桁では常に最大数から引き算をしているため「繰り下がり」を考えずに計算することができます。
9 9 ← 繰り下がりがない。 - 0 4 9 5
上記と同じ条件 (10 進数 2 桁で減数 -4) で実際の計算をしてみます。2 進数は構造が単純
「7 - 4 = ?」は、いくつになるでしょうか、3 ですね。
これを、
「7 + (-4) = ?」と変形してみます。
すると、
「7 + (基数の補数) = ?」とすることができます。(最上位の桁上がりを無視しなければなりませんが···)
なので、
「7 + 96 = 103」となり、さらに最上位の桁上がり 1xx を無視すると、3 が求まります。
もともと「10 進数 2 桁で」という条件なので、問題ありません。
また、条件とする桁数に制限はありません。(ゼロ桁とかはダメですよ)
かなりずるいとは思いますが、補数を使って「引き算の式」を「足し算の式」にすることができました。
実はコンピュータは、引き算より足し算のほうが得意 (高速) なのです。
10 進数を使うには 10 種類の数字を使うのと同様に、2 進数で補数を使うと引き算がなくなる
2 進数を使うには 0 と 1 という 2 種類の数字を使います。
10 進数の場合は、10 個目の数字で桁上がりになるので、0, 1, 2, 3, ··, 8, 9, 10, 11, ··, 19, 20, 21, ·· と続きます。
2 進数の場合は、2 個目の数字で桁上がりになるので、0, 1, 10, 11, 100, 101, ··, 1111, 10001, 10010, 10011, ·· と続きます。
数え方が違いますが対象物の数は変わらないので、1 対 1 で相互変換できます。
(例えば、リンゴが 10 進数で 3 個なら、2 進数で 11 個と数えますが、リンゴの数は変わりません)
2 進数と 10 進数の対応表2 進数は一番単純なので、電子回路を作りやすいという特徴があります。
2 進数 10 進数 0 0 1 1 10 2 11 3 ··· 1000 8 1001 9 1010 10 1011 11 ··· 111111 63 1000000 64 ···
例えば、0 から 1000 を数えるとき、2 進数なら単純な電子回路 10 桁分を並べれば作れますが、(1,000 は 210 = 1,024 に入れることができる)
10 進数の電子回路を 4 桁分並べる方がはるかに複雑になり、電力も多く必要になります。
10 進数と 2 進数で相互変換ができるなら、数学的に一番単純な 2 進数でコンピュータを作ったほうがいいという選択になりました。
(10 進数のコンピュータを作れないわけではないけど、効率が悪い)
例: 3 + 4 = 7 を電気的に 2 進数と 10 進数で計算
• 2 進数の場合
· 比較回路が単純になるため、回路の専有面積が小さい ⇒ 製造コストが低い。
· 2.5V を境に 0 と 1 で分けるため、少しくらい電圧の誤差があっても動作可能 ⇒ 製造コストが低い。
+5V
+
=
0V
• 10 進数の場合
· 比較回路が複雑になるため、回路の専有面積が大きい ⇒ 製造コストが高い。
· 0~0.50V を 1 単位とするため、電圧の誤差が大きいと動作不能 ⇒ 製造コストが高い。
+5.00V
+
=
+4.50V
+4.00V
+3.50V
+3.00V
+2.50V
+2.00V
+1.50V
+1.00V
+0.50V
0.00V
上記「10 進数の補数」では、10 進数の補数を使って引き算をしました。負の 10 進整数
2 進数でも同じように計算できます。
上記と同様に「7 - 4 = ?」を考えます。
10 進数 2 桁分の計算をするには、2 進数だと 7 桁*1を必要とし、最大値は 127 です。(27 - 1 = 1111111(2 進数) = 127(10 進数))
なので、
です。
減基数の補数は 123。 → 127 - 4。 2 進数で 1111011 基数の補数は 124。 → 127 - 4 + 1。 2 進数で 1111100
10 進数の 7 を 2 進数にすると、111 です。
なので、
「7 - 4 = ?」(10 進数)を
「7 + (基数の補数) = ?」(10 進数)に変形して、
「0000111 + 1111100 = ?」(2 進数)となります。
これを計算すると、
10000011(2 進数) となり、7 桁の計算なので最上位の桁上がり 1xxxxxxx を無視して、0000011(2 進数) (= 3(10 進数)) が求まります。
興味深いのは、2 進数の「減基数の補数」は、引き算をするのではなく、各桁の数値をすべてひっくり返せば求めることができるという点です。
これを「1 の補数」と呼びます。
同様に「基数の補数」(減基数の補数に 1 を加算したもの) を「2 の補数」と呼びます。
2 進数における「減基数の補数」と「基数の補数」の関係 (引き算をしていない)引き算を使わないのに、引き算ができてしまいました。
7 桁の計算なので、8 桁目は無視します。
減数 1 の補数 2 の補数 各桁をひっくり返す
→さらに+1する 0000000 1111111 10000000 0000001 1111110 01111111 0000010 1111101 01111110 0000011 1111100 01111101 ··· 0001000 1110111 01111000 0001001 1110110 01110111 0001010 1110101 01110110 0001011 1110100 01110101 ··· 0011111 1100000 01100001 0100000 1011111 01100000 ···
*1興味のある人は、覚えておくといいことがあります。
102 → (2 - 1) ≦ log10X < 2 1 ≦ log2X / log210 < 2 1 ≦ log2X / (log1010 / log102) < 2 1 ≦ log2X / (1 / 0.3010) < 2 102 = 23.3223 ~ 6.6446 → 26.6446 を格納できる整数は 27。
1 / 0.3010 ≦ log2X < 2 / 0.3010 3.3223 ≦ log2X < 6.6446
負の整数とは、0 より小さい整数のことです。負の 2 進整数
10 進数では、-1, -2, -3, .., と続く決まりです。
0 からいくつ引き算したかを表す数字なので、
0 - 1 = -1です。
0 - 2 = -2
0 - 3 = -3
···
いくつ足し算したら 0 になるかを考えます。
つまり、
0 = -1 + 1ですね。
0 = -2 + 2
0 = -3 + 3
···
2 進数で負の整数を表すときは、10 進数の時と同様に、2 進数を使うと都合が良い
0 からいくつ引き算したかを表す数字になりますが、10 進数の「-」(マイナス記号) の代わりに、最上位の 1 をマイナス記号として使います。
マイナスの数を 3 桁の 2 進数にする場合は、最上位の 1 を削って、2 桁の 2 進数を扱います。
3 桁の 2 進数だだし、-1(10 進数) を 1 01 (2 進数) とはしません。
マイナス記号 数値 1 xx
いくつ足し算したら 0 になるかを考えるので「2 の補数」(最上位桁の繰り上がりを無視) を使って、1 11(2 進数) と表します。
-1 の場合: 0 00 = 1 11(2 進数) + 1(10 進数)負数を考慮に入れた整数は以下の様になります。
-2 の場合: 0 00 = 1 10(2 進数) + 2(10 進数)
3 桁の 2 進数と 10 進数の関係 (負の数を表すために、上記の関係表と逆順にしています)
*2 3 桁の 2 進数では -4 ~ 3 (100 ~ 011) の 8 種類の数字を数えることができます。
3 桁の 2 進数*2 | 0 との差 | 10 進数 マイナス記号 数値 | | 0 11 | 0 11 | 3 0 10 | 0 10 | 2 0 01 | 0 01 | 1 0 00 | 0 00 | 0 1 11 | 00 00 = 1 11 + 0 01 | -1 1 10 | 00 00 = 1 10 + 0 10 | -2 1 01 | 00 00 = 1 01 + 0 11 | -3 1 00 | 10 00 = 1 00 + 1 00 | -4
以上の様に、2 進数を使うことにより、
と、すべてにおいて都合が良いのです。
- 電子回路が複雑にならない。(小さく作れる。省電力)
- 引き算を足し算にすることができる。(繰り下がりがないので引き算より高速)
PC やスマートフォンのサイズや消費電力を小さくできるのは、これ以外にも様々な技術で成り立っています。