2進数と16進数

2進数

計算機の内部では、数値も文字も画像も全て 1 と 0 の2進数 で保存している。コンピュータが何かを記憶するためにはメモリ に格納する必要があり、メモリに書き込むためには電気的(あるいは磁気的) に ONかOFFかの形で書くことになるからである。これを何個も組み合わせて一つの データ格納領域とする。たとえば、ONとOFFの箱を8個用意して、 次のようなデータを入れる。

OFFONOFFOFF OFFOFFOFFON

これは模式的な絵であるが、コンピュータのメモリの中では、 電気がONになっていたり、磁石がN極を向いている状態を想像するのが実状に近 いだろう。このOFFとONの状態を、2進数にしよう。

0100 0001

2進数の 01000001 になる。2進数を10進数に直すときは、各桁を以 下のような倍率を掛けたものを足して行けば良い。

128倍64倍32倍16倍 8倍4倍2倍1倍
0100 0001

これは、64×1 + 1×1 = 65 となる。

16進数

いくら計算機が内部で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進数
000000
000111
001022
001133
010044
010155
011066
011177
100088
100199
1010a10
1011b11
1100c12
1101d13
1110e14
1111f15

ONとOFFの箱で出てきた、

OFFONOFFOFF OFFOFFOFFON

つまり

0100 0001

は、16進数で表すと4桁毎に変換すれば良いので

となる。2進数 01000001 は、16進数で41である。 ちなみに41は文字コードでいえば、アルファベッ ト大文字Aに該当する。つまり、Aという文字を計算機の内部に記憶させたいとき は

0100 0001

のようにデータが格納されることになる。

16進数と10進数の変換

16進数を10進数へ

16進数を10進数に変換するには、各桁に16の倍数を掛けたものを足す。 たとえば、16進数 0x56ce

を10進数に直してみよう。
4096倍
(16**3)
256倍
(16**2)
16倍1倍
56ce

cの桁は10進数で12を意味することと、eの桁は10進数で14を意味することに 注意して計算すると、

4096*5 + 256*6 + 16*12 + 14 = 22222

となる。

10進数を16進数へ

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プログラムでの扱い

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です

本日の目次