昔の人は数を表すのに、両手の指で足りないときは石を並べたり していたのでしょうか。今でも 10 以上は「たくさん」ですませてしまうところも、 地球上のどこかにはあるかもしれませんね。
これではめんどうなので、「n 進数」という考え方ができたのでしょう。 今の世の中では 10 進数がメジャーですが、これは両手の指の数の合計から 来たことは想像にかたくありません。
ご存知のように、10 進数では 0 〜 9 までの 10 個の「記号」を 並べて行けば、理論上どんな整数でも表すことができるようになっています。 数を表す記号の種類が 10 進数の場合 10 種類なわけですね。
ところが、10 という数字は 1 種の決め事であり、 世の中には 10 進数以外の数え方で考えるものもたくさんあります。 たとえば時間は 10 進数で表現しますが 60 とか 24 とかいう中途半端な単位で 繰り上がりますね。聞いたところによると、フランス語では 60 進数みたいな 数え方をするらしいです。ただし 1 進数はありません。これでは0しか 表せないからです。
コンピュータの世界では、物理的には電気のオン−オフをそのまま 情報として使用するのが都合が良かったので、ここから 2 進数が生まれたんだと 思います。たとえば電気が通じている状態を 1、切れている状態を 0 (またはこれらの逆)で表すようにしたわけです。2 進数では記号が 2 つしか 必要としないので、もともとあった数字のうちの 0 と 1 が使われています。 この 1 桁の 0 または 1 を記憶する単位のことを ビットと呼びます。
2 進数では記号が 2 種類しかないので、 ある数を表すときに 10 進数より多くの桁数を必要とします。
10 進数 | 2 進数 |
---|---|
0 | 0 |
1 | 1 |
2 | 10 |
3 | 11 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
8 | 1000 |
なんだか覚えづらいですね。
これを、単なる数の羅列で考えるのではなく、ある規則性を持たせてみましょう。実は、2 進数は 2 のべき乗表現で表すことができます。下の図を見てください。ここで、'^'はべき乗を、'*'は掛け算を表します。
この表では、2 進数の 8 桁表現を併記しています。理由は、コンピュータ内部で使われる記憶領域の数え方(=メモリ上の記憶の単位)は、上記の「ビット」ではなく、バイト(=8 ビット)が使われるからです。つまり、0 という 1 ビットで表現可能な数を記憶するために、コンピュータ内部では最低でも 8 ビット分の記憶領域が消費されます。
10 進数 | (2 のべき乗表現) | 2 進数 | (8 桁表現) |
---|---|---|---|
0 | (2^3)*0+(2^2)*0+(2^1)*0+(2^0)*0 | 0 | 00000000 |
1 | (2^3)*0+(2^2)*0+(2^1)*0+(2^0)*1 | 1 | 00000001 |
2 | (2^3)*0+(2^2)*0+(2^1)*1+(2^0)*0 | 10 | 00000010 |
3 | (2^3)*0+(2^2)*0+(2^1)*1+(2^0)*1 | 11 | 00000011 |
4 | (2^3)*0+(2^2)*1+(2^1)*0+(2^0)*0 | 100 | 00000100 |
5 | (2^3)*0+(2^2)*1+(2^1)*0+(2^0)*1 | 101 | 00000101 |
6 | (2^3)*0+(2^2)*1+(2^1)*1+(2^0)*0 | 110 | 00000110 |
7 | (2^3)*0+(2^2)*1+(2^1)*1+(2^0)*1 | 111 | 00000111 |
8 | (2^3)*1+(2^2)*0+(2^1)*0+(2^0)*0 | 1000 | 00001000 |
どうでしょう。2 進数の(右から数えて)1 桁目は 2 の 0 乗(つまり 1)が何個あるかを表し、同様に 2 桁目は、2 の 1 乗(つまり 2)が何個あるかを表していますね。これを一般化すると、
ためしに 2 進数の「00110001」を 10 進数に変換してみましょう。今後は便宜上 2 進数は「」でくくることにします。
「00110001」
= (2^5)*1 + (2^4)*1 + (2^0)*1
= 32 + 16 + 1
= 49
ということで、「00110001」は 10 進数では 49 となります。
今度は、10 進数の 123 を 2 進数に変換してみましょう。
2 進数の各桁は、それぞれ 2 の n 乗があるかないかを示しているということができます。では、2 の n 乗の値を具体的に羅列してみると、以下のようになります。分かりやすいように、右から書いています。
ここで、10 進数 123 はこの中の最大どの数を含んでいる(その数より大きい)かを考えてみますと、128 よりは小さくて、64 を含んでいることがわかります。64 は上記の右から数えて 7 番目ですから、123 を 2 進数に直すと 7 桁になり、1 番大きい桁は 1 となります。つまり、「1??????」という数になります。
次に、先頭の 1 は確定したので、残りの数を求めるために先頭の 1 を除外します。除外するとはすなわち引くことなので、残りの数は
となります。59 は 64 の次の 32 を含んでいますので、6 桁目にも 1 が立ちます。つまり、
96 まで確定したので、残りの数を求めるためには、
です。同様にして、
除外した数 | (10 進表記) | 引いた残り | |
---|---|---|---|
1000000 | (64) | 59 | |
+ | 100000 | (32) | 27 |
+ | 10000 | (16) | 11 |
+ | 1000 | (8) | 3 |
+ | 10 | (2) | 1 |
+ | 1 | (1) | 0 |
----------------------------------- | |||
1111011 |
となるわけです。これを応用すればなんとか計算できるようになりますが、いかんせん 1 と 0 だけでは見やすいとはいえませんね(私もさんざん間違えて、いろいろな方にご指摘いただきました。この場を借りてお礼申し上げますm(__)m )。そこで登場するのが16進数です。
123 が「1111011」になるのは何とかおわかりいただけたのではないかと思いますが、これは人間にとってとても見やすい数字とはいえません。
人間にとって見やすく、かつコンピュータにとっても割と都合がいい表記法として、16 進数というのがあります。これは、
というものです。つまり、123 の 2 進表現である「01111011」(「1111011」を 8 桁表現にするために、先頭に 0 を付加したもの)を「0111 1011」と表記し、これを 2 桁の記号でと表そうというわけです。
4 ビットずつに分けると、各々のかたまりについてのパターンが 0000 〜 1111 まで 16 通りありますね。(理解できない方は、紙に書いて確かめてください(^^; 1 桁で 0 または 1 の 2 通りですから、4 桁あると 2 × 2 × 2 × 2 で 16 通りになるはずです。)16 通りの数字を 1 桁で表すために 16 個の記号が必要になるので、16 進数というわけです。
0 〜 9 では 10 種類しかないですから、ここは短絡的にアルファベットの A 〜 F を拝借することにしたようです。ということで、変換表は以下のようになります。この分だけは完全に暗記して、即時に変換できるようにしておいてください。
10 進数 | 2 進数 | 16 進数 |
---|---|---|
0 | 0 | 0 |
1 | 1 | 1 |
2 | 10 | 2 |
3 | 11 | 3 |
4 | 100 | 4 |
5 | 101 | 5 |
6 | 110 | 6 |
7 | 111 | 7 |
8 | 1000 | 8 |
9 | 1001 | 9 |
10 | 1010 | A |
11 | 1011 | B |
12 | 1100 | C |
13 | 1101 | D |
14 | 1110 | E |
15 | 1111 | F |
先に例を挙げた 123 の 2 進表現である「0111 1011」を、この表を元に 16 進数に変換してみると、「7B」になるのがお分かりいただけると思います。
これも 2 進数と同様で、2 のべき乗のところが 16 のべき乗に変わるだけです。では、いくつか例を示します。便宜上、16 進数は XXh と表記します。
100h
= (16^2) * 1 + (16^1) * 0 + (16^0) * 0
= 256
FFh
= 100h - 1h
= 256 - 1
= 255
FFFFh
= 10000h - 1h
= (16^4) * 1 + (16^3) * 0 + …… + (16^0) * 0 - 1
= (16^2) * (16^2) - 1
= 256 * 256 - 1
= 65536 - 1
= 65535
では、この調子でがんばってマスターしてください\(^。^)/。