計算機の内部では、数値も文字も画像も全て 1 と 0 の2進数 で保存している。コンピュータが何かを記憶するためにはメモリ に格納する必要があり、メモリに書き込むためには電気的(あるいは磁気的) に ONかOFFかの形で書くことになるからである。これを何個も組み合わせて一つの データ格納領域とする。たとえば、ONとOFFの箱を8個用意して、 次のようなデータを入れる。
OFF | ON | OFF | OFF | OFF | OFF | OFF | ON |
これは模式的な絵であるが、コンピュータのメモリの中では、 電気がONになっていたり、磁石がN極を向いている状態を想像するのが実状に近 いだろう。このOFFとONの状態を、2進数にしよう。
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
2進数の
128倍 | 64倍 | 32倍 | 16倍 | 8倍 | 4倍 | 2倍 | 1倍 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
これは、64×1 + 1×1 = 65 となる。
いくら計算機が内部で2進数を使うとはいえ、2進数のまま数値を書いたので は長くて読みづらい。かといって、10進数に直すのは計算が面倒である。そのた め、2進数4桁をまとめて16進数にして数値を表記することが多い。
たとえば、10進数でもまとめて表記することがある。長さの尺度が「メート ル」のまま距離を表現したら大変なので、10進数3桁(10の3乗=1000)ごとにまと めて「キロ」メートルで表現することがある。逆に、10の-3乗メートルを「ミリ」 として表記したりする。また、金額を表記するときも3桁毎にまとめて 2,500,000円 のように10の3乗ごとにまとめてあたかも1000進法のようにして表 すことがある。このように何桁かをまとめて単位を付けたりすることは日常的に も身近なことである。
2進数4桁をまとめると、2**4=16個の数を表すことができる。
2進数 | 16進数 | 10進数 |
---|---|---|
0000 | 0 | 0 |
0001 | 1 | 1 |
0010 | 2 | 2 |
0011 | 3 | 3 |
0100 | 4 | 4 |
0101 | 5 | 5 |
0110 | 6 | 6 |
0111 | 7 | 7 |
1000 | 8 | 8 |
1001 | 9 | 9 |
1010 | a | 10 |
1011 | b | 11 |
1100 | c | 12 |
1101 | d | 13 |
1110 | e | 14 |
1111 | f | 15 |
ONとOFFの箱で出てきた、
OFF | ON | OFF | OFF | OFF | OFF | OFF | ON |
つまり
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
は、16進数で表すと4桁毎に変換すれば良いので
0100
→ 4
0001
→ 1
となる。2進数 01000001
は、16進数で41
である。
ちなみに41は文字コードでいえば、アルファベッ
ト大文字Aに該当する。つまり、Aという文字を計算機の内部に記憶させたいとき
は
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
のようにデータが格納されることになる。
16進数を10進数に変換するには、各桁に16の倍数を掛けたものを足す。 たとえば、16進数 0x56ce
を10進数に直してみよう。4096倍 (16**3) | 256倍 (16**2) | 16倍 | 1倍 |
5 | 6 | c | e |
cの桁は10進数で12を意味することと、eの桁は10進数で14を意味することに 注意して計算すると、
4096*5 + 256*6 + 16*12 + 14 = 22222
となる。
10進数を16進数に変換するには、元の10進数を割れなくなるまで16で割り、 割ったときの余りを逆に拾って行けば良い。たとえば、10進数64206を16進数に 直してみよう。
16) 64206 16) 4012 …… 14 余り → e 16) 250 …… 12 余り → c 16) 15 …… 10 余り → a 16) 0 …… 15 余り → f ↑下から上に読む
割り算の余りを下から順に読んだ、0xface が16進の値となる。
Rubyプログラムでは、プログラム中に書く数値の先頭に付ける記号(接頭辞)で 何進法かを指示できる。
接頭辞 | 意味 |
---|---|
なし | 10進数 |
0b | 2進数 |
0 | 8進数 |
0x | 16進数 |
0b1010
は、2進数の1010
(10進数でいえば10を)
表すことになり、0x10f0
は、16進数の 10F0 (10進数でいえば
4336)を表すことになる。
プログラム中に、0b1010
と書こうが 10
と書こ
うが、0xa
と書こうが、一度読み込まれれば計算機の内部ではど
れも10進数でいうところの10として扱われ、どれも全く同じである。これを出力
するときに何進法にするかは printf
の%つきフォーマットで選
択することができる。
以下に、printf
の%フォーマットで
数値を何進法で出すかの意味を示す。
%フォーマット | 何進法で出力されるか |
---|---|
%b | 2進法 |
%o | 8進法 |
%d | 10進法 |
%x | 16進法 |
これを利用すると、16進数を10進数に直したり、その逆をしたりすることを Rubyプログラムに任せることができる。
printf "16進の%xは10進で%dです\n", 0x555, 0x555 ↓ 16進の555は10進で1365です
printf "10進の%dは2進で%bです\n", 2002, 2002 ↓ 10進の2002は2進で11111010010です