タイトルAround the System and Development》16進数に慣れようカテゴリーAround the System and Development
作成日2002/2/16 14:58:11作成者新居雅行
0と1があれば、コンピュータの中身や動作がすべて記述できると言っても過言ではない。だけど、ちょっとしたデータでもすぐに桁が長くなってしまうのは容易に想像できる。それに、桁が多くなると間違えやすい…などなど、人間はより適した手法を見つけようとするものである。もちろん、2進数も10進数も数値という意味では同じもので表記方法が違うだけだ。だったら10進数でもいいじゃないかと思うところだが、結果的には10進数はテクニカルなレベルでは実はあまり用いられて来なかった。例外的にIPアドレスというところで10進数が使われているが、むしろ、8進数や16進数が使われているのである。

8進数や16進数は、それぞれ1桁が8ないしは16通りの数字や記号を使って、数値を表す。8進数は、0〜7の数値を使う。8進数だけど「8」という数値がないことに、まずは驚くかもしれないが、10進数だって、10を示す1桁の数字はないのだから、その意味では同じようなものだ。一方、16進数となると、ちょっとやっかいだ。0〜15と書くと妙に感じる。1桁の数字を示すのに10とか11を使うのかと言う問題になる。そこで、10〜15に対応する数字としてアルファベットのA〜Fを割り当てた。もちろん、a〜fの場合もある。だから、0123456789ABCDEFということで、16通りなのである。これらの数字や記号を1桁に記述する。
ここでこれらの数値についての表記は軽く流すことにするが、16進数はHexdecimalの意味で、数値の後に「H」をつけて記述する。つまり、10進数の対応を取ると、10=AHである。つまり、9の次はAであるが、16進数を示すためにHをつけた。すると、15=FH、16=10H、25=19H、32=20H…というわけだ。本来なら、公文式のペーパーテストのような(笑)練習問題をつけたいところだが、16進数は自然に覚えてしまうくらいになるだろうから、さておくことにする。
それじゃあ8進数だが、Octalだから「O」を後につけたいところだが、ここでは分かりやすいように小文字で「o」にしておこう。大文字だと、数字の0と区別がつきにくい。8進数だと、8=10o、9=11o、15=17o、16=20o…となる。
ところで、何進数かというのを示すのに、BやHをつけるというのは、数学の本で見た記憶があるのだが、申し訳ないが出展は明らかではない。だから、8進数をどう書いていたのかは思い出せなかった。いずれにしても、単に記述の問題だけである。ただ、プログラム上ではこれらの数値の記述方法はプログラミング言語の処理系に依存する点は心にとめていただきたい。なお、ここでの何進数かという意味の数値、つまり、1桁が何通りのバリエーションを持つのかという値を「基数」という。英語ではbase numberやradixである。

また、「なぜか」を追求したい。なぜ8進数や16進数だと、いいのか? それは、8進数や16進数の桁区切りの場所が、2進数の桁区切りの場所と一致するのである。つまり、2の3乗が8だし、2の4乗が16であるところから、結果的に、2進数3桁を8進数1桁にまとめることができる。また、2進数4桁を16進数1桁にまとめることができる。これは、例を出すのが早いだろう。

001101010
└─┘└─┘└─┘
 1  5  2
 └──┘└──┘
   6   A

つまり、1101010B=152o=6AHということだ。ちなみに10進数では106となる。2進数部分はわざと9桁にしてある。
たとえば、2進数と10進数の関係を見れば分かるように、桁の対応がほとんど取れていない。だから、2進数を10進数に変換することや、あるいはその逆はもちろん数学上の手続きを経れば可能だけど、ちょっとやっかいだ。慣れれば暗算は可能だけど、あまり一般的な技能とは言えないだろう。ところが、8進数や16進数だと、2進数の3ないしは4桁ごとに変換すれば、それぞれ相互に変換することができる。たとえば、101100101010101001010111110001なんて2進数が示されて、これを16進数で記述せよと言った場合、機械的に下の桁から4桁ごとに区切る。10 1100 1010 1010 1001 0101 1111 0001となる。そして、それらを4桁のブロックごとに順番に16進数に置き換えればよい。10→2、1100→C、1010→Aというわけで、最初に示した桁のたくさんある2進数を16進数で表現すれば、2CAA95F1Hというわけだ。逆も同様である。だから、はっきり言って誰でもできる範囲のことなのだ。
ところで8進数なんて見たことがないぞといういう方も多いかもしれない。この理由はもうお分かりだろう。8進数だと、2進数の桁数、つまりビット数が3、6、9など3の倍数の場合には、過不足なく対応が行われる。だが、現在のコンピュータの中は8ビットが基調になっている。そうすると、8ビットは16進数2桁でぴったり収まる。そうしてコンピュータにメモリされたりする値などは16進数で表現することが一般的になったのである。もし、9ビットのコンピュータ主流になっていれば、もしかすると16進数なんて使われずに8進数がテクニカルな世界ではメジャーになっていただろう。
もっとも、8進数でもかまわないと言えばかまわないのである。8進数3桁で1バイトは表現できるけど、最初の桁は2ビットだから、1バイトの値は8進数だと、000o〜377oということになる。別にこれでもかまわないのだけど、8進数3桁だと、9ビットということで対応が悪い。こういう気持ち悪さは避けたいので、やっぱり16進数が主流ということになるわけだ。だが、稀に8進数も使うときがあるので、やはり基本としては押さえておきたい。
だからなれてくると、16進数は2進数に見えると表現すれば良いだろうか。35Hは下から3番目のビットは1だ(こういう場合、「ビットが立っている」という)。だけど、D3Hだと下から3番目のビットは立っていない…という風に頭が働くようになる。コンピュータのCPU等では特定のビットに状態などを割り当てていることがよくあるため、その種の開発などをやっていれば、こうした技能は否応なく身につく。だけど、それは、2進数を扱いやすくした16進数というものの存在のおかげであるということなのである。

ところで、こんなことをどこで覚えたかと言うと、実は、その昔に使っていたワンボードコンピュータでのプログラミングである。筆者だと20前後の頃で、昭和50年代だ。当時は若かったのでこういう複雑怪奇なことにも追随できたし、さらにはこういうことを知らないと何もできなかったので身についたが、今ではこういうことを知らなくてもパソコンは使える。しかし、ファイルの中身やメモリの中身をのぞいてチェックするような場合には、その当時に身につけていたことが今でも大きく役立っているのである。ユーザから見たコンピュータシステムは、現在ではさまざまなベールや仮面を多重にかぶって中身が見えなくなっている。だけど、システムをいじったり、プログラミングを行うとなると、仮面を取り除いてベールをはがさないといけないことも多いのである。ワンボードマイコンを使いこなせるくらいに知る必要もないのかもしれないが、16進数や2進数にひるまない程度に少しはトレーニングしておくと、その後の理解は非常に楽になるだろう。
関連リンク