教科書等では十六進法はさらりと軽く扱っていますが、ここではゆっくり書いてみます。
十六進法は二進法を学んだ人にはそんな難しくはありません。なぜなら数学的な意味は別として、情報の世界では「二進法を簡単に記述する」ため(だけ)に十六進法が使われているからです。
二進法を改めて確認します。
※(10)は十進法、(2)は二進法という意味。本当は下付きの小さな文字なのですが、Web上では表しにくいので半角の普通の大きさの文字にしています。
5(10)=101(2)
18(10)=10010(2)
92(10)=1011100(2)
733(10)=1011011101(2)
2546(10)=100111110010(2)
59321(10)=1110011110111001(2)
全部暗算で変換できましたか?冗談です無理に決まってますね。
でも、5と18ぐらいはできて欲しいです。
(え?よくわからない?ちょっ、ちょっと待った!!上記5(10)と18(10)を二進法に変換するのができていない人は、この先に進むのはやめて、もう一度「二進法とは」に戻ってください。紙とペンを使って自分で変換できるようになってからここに戻ってください)
閑話休題。
さて、二進法ではだんだん桁が爆発していくことが分かるでしょうか?
上記を見ると、5(10)は3桁(3bit)で済んでいますが、59321(10)になると16桁(16bit)必要です。
コンピュータは処理できる範囲の中であれば「桁が多すぎる!」などと文句を言ったりはしませんが、人間が間違えます。ホントよく間違えます。
そこで二進数を4桁ずつ区切って、その4桁それぞれを一文字で書き表すことにしました。それが十六進法です。
以下、流して読まず一行ずつしっかり確かめてくださいね。
0000(2)=0(10)=0(16)
0001(2)=1(10)=1(16)
0010(2)=2(10)=2(16)
0011(2)=3(10)=3(16)
0100(2)=4(10)=4(16)
0101(2)=5(10)=5(16)
0110(2)=6(10)=6(16)
0111(2)=7(10)=7(16)
1000(2)=8(10)=8(16)
1001(2)=9(10)=9(16)
9までは十進法の数字そのままです。
二進法で次の「1010(2)」は十進法だと「10(10)」と2桁(2文字)になってしまう。さきほど「一文字で書き表すことにした」ので困ってしまう。
そこで十進法「10(10)」に相当する一文字の「数字」として「A」を割り当てることにしました。
以下、11、12、13、14、15に相当する「数字」として、B、C、D、E、Fを割り当てることにします。
気を付けてください。このA~Fは「数字」なのです。これを用いると上記数式の続きは次のようになります。
1010(2)=10(10)=A(16)
1011(2)=11(10)=B(16)
1100(2)=12(10)=C(16)
1101(2)=13(10)=D(16)
1110(2)=14(10)=E(16)
1111(2)=15(10)=F(16)
これで二進数4桁すべてを一文字(十六進数1桁)に置き換えることができました。
「二進法は桁が多いから二進数4桁を1文字(1桁)で表すために十六進法を使う」ということと、その対応関係は分りましたでしょうか。
では二進数5桁以上(十進数で16以上)の数値を表すにはどうすればいいでしょうか?
10000と5桁になったら、二進数4桁ずつにするために、1の前に「000」を置いて「00010000」と8桁にします。
10000(2)=00010000(2)=0001 0000(2)
4桁ずつ、それぞれを十六進数1桁に割り当てます。
0001 0000(2)=10(16)
二進数5桁→十六進数2桁の基数変換ができました(※最後、ややこしいですが「10」と書いていますが「じゅう」ではなく十六進の「イチゼロ」であり、十進法では「16(じゅうろく)」を意味します)。
上記の表の延長として考えると、
14(10)=E(16)
15(10)=F(16)
16(10)=10(16)
とFの次に桁上がりします。
というわけで、どんなに長い二進数であっても、小さい方から4桁ずつにして、対応表で十六進数一文字ずつに置き換えるだけです。
たとえば最初に書いた二進数は十六進数で表すと次のようになります。
5(10)=101(2)=0101(2)=5(16)
18(10)=10010(2)=0001 0010(2)=12(16)
92(10)=1011100(2)=0101 1100(2)=5C(16)
733(10)=1011011101(2)=0010 1101 1101(2)=2DD(16)
2546(10)=100111110010(2)=1001 1111 0010(2)=9F2(16)
59321(10)=1110011110111001(2)=1110 0111 1011 1001(2)=E7B9(16)
といった感じです。桁が少なくてスッキリしましたね!
二進←→十六進は0000(2)~1111(2)までの表さえあればいいのです。変換しろと言われたら表を見ながら置き換えてください。まぁこの表ていどは全部覚えて欲しいのですが。
以上でやり方は分ったかと思いますので、練習問題をやってみてください。
基数変換のやり方は分った。もう少し十六進法を考えたいという方へ。
二進法は、0,1,10,11,100,101,110,111,1000,……
十進法は、0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,……
十六進法は、0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20,21,……
と増える数であることはよろしいですか?
十六進法は十六倍すると桁が一つ上がる表記法ということで、以下の関係になります。
1(16)=1(10)
10(16)=16(10)
100(16)=256(10)
1000(16)=4096(10)
10000(16)=65536(10)
このぐらいわかっていれば十分です。十六進数どうしの足し算引き算など基本的にしません。十進←→十六進の基数変換をすることもめったにありません!十六進の相手は二進だけと思っていい。もし十進との変換が必要なら電卓でやりましょう。テストには……出さないんじゃないかな。たぶん。
一応上記の太線の関係ぐらいは知っていてください。ゲームでは、「アイテムは256種類です」とか、「ゴールドを65535Gより持つことはできない(ファミコン版ドラゴンクエストII)」などの制限があるのを聞いたことがある、かな?上の数式と見比べると、ピッタリとした数値だったんだなということが分かると思います。アイテム256種類ということは十六進数2桁00~FF(二進数8桁00000000~11111111)でアイテムの番号を振っていた、つまりゲームプログラム内部で8bit=1バイトで処理しているということです。このゲームでゴールドは2バイトのデータ処理だったので最大値FFFFだったのですね。
コンピュータ処理において、「FF」と聞いたら8bit最大値の「1111 1111だな」とピンとくるようになるといいですね。
また話は違いますが、十進と同じ数字しか出てこないときは気をつけろ!ということ言っておきたい。
「僕20歳です。ただし十六進法で」
と言われたらこの人は「32(10)歳」です。騙されないようにしてください。
2D(16)=45(10)
のようにA~Fが含まれていればまだピンとくる気がしますが、
82(16)=130(10)
など頭の中「???」となりますよね。計算して確かめてみてください。
またDF(16)が数字だとなかなか思えなかったりします。一応書くと223(10)です。慣れです。
電卓でできないのかと思う方もいると思いますが、できます。Windowsの方はWindowsアクセサリの中にある「電卓」を起動し、表示を標準→プログラマーにモードを切り替えてください。二進←→十進←→十六進の基数変換が簡単にできます。Macの方はよくわからないのですが、たぶんできます。
スマートフォンでは、iPhoneでは「開発者電卓」、Androidでは「開発者関数電卓」が便利だと思います。
さきに言ってよ!って?まぁそうすると勉強にならないので。
十六進法を学んで、二進←→十六進ができるようになると、二進←→十進の時と混同してしまいがちです。
「24(10)を二進数に変換しなさい」という問題があったとき、
「かんたんかんたん。「2」は「0010」で「4」は「0100」だから「0010 0100」でしょう?」
という人がでてきますが、それ間違いですから!それは十六進の「24(16)」の時だから。
十進からの変換は
24=16+8+0+0+0
24(10)=11000(2)
ですよ。頭がこんがらがった方はもう一度「二進法とは」のページで確認しましょう。
二進、十進、十六進の3種類学んだあとに分かるのは、
「結局、十進との変換だけ面倒くさい」
のです。人間の使っている十進はメンドウなのです。
どうでもいいような話なので読まないで欲しいのですが、この「国分寺高校情報科サイト」を読んできて、なぜ清水先生は「十進法」の「十」のような漢数字を使うのだろう?と思った人はいましたか。これは清水のこだわりでありまして、教科書もNHK高校講座も「10進法」などアラビア数字「10」を使っていますが、これ、何進法の「10」なの?ってなりませんか?二進法の「10」なら「10進法=二進法」になっちゃうし、十六進法の「10」なら「10進法=十六進法」ということになりますよね?「十(じゅう)」と漢字で書けば「○○○○○ ○○○○○」の丸の数のかたまりという意味になりますよね。屁理屈かも知れませんが、まぁそんなところを気にして書いていたりします。生徒の皆さんはどちらで書いても問題ないと思います。
さらに脱線すると、漢数字も純粋なアラビア数字の十進表記と一文字一文字ずつの対応ではありませんね。123456=十二万三千四百五十六ですから。そんなことをいうと英語の数え方は?ローマ数字の書き方は?1ダースが12個で12ダースが1グロスは十二進法?時計は六十進法?テニスの得点変じゃない?円はなぜ360度なの?そもそも十進法はなぜ「10」なの?などなど……。情報とはまったく関係ないのですが興味のある方は調べてみると深い文化・歴史がわかって面白いですよ。
また「十進法」と「十進数」の「法」と「数」ですが、世の中圧倒的に「十進数」と書くの方が多いですね。私としては十ごとに桁が上がる数の表記法(ルール)として「十進法」、十進法であらわされた数(ナンバー)という意味で「十進数」と一応なんとなく使い分けて書いているつもりです。
質問がありましたので注意点を追加します。
【質問】10進数の4を2進数に変換するとしたら、0100(2)と表すのですか?100(2)でも大丈夫ですか?
---教科書の答えの書き方に一貫性が無いですね。結論としては「どちらでも大丈夫です」。100(2)と0100(2)はまったく同じです。
ただし、十六進数2桁を二進数に直すときなどの下位(小さい位)では前の「0」は省略できません。たとえば、
【問】十六進数「E5(16)」を二進法で表しなさい
と言われたとき、E(16)=1110(2)、5(16)=0101(2)なので
1110 0101(2)
が正解です。しかし、ここで下位を5(16)=101(2)としてしまい「1110 101(2)」などと書くと違う数になってしまいます。
1110 0101(2)=128+64+32+0+0+4+0+1=229(10)
1110 101(2)=64+32+16+0+4+0+1=117(10)
です。なので、途中の「0」は省略してはいけません。一番大きな位の「0」は書いても書かなくても良い。ただし、4桁ずつになっていた方が読むほうが間違えにくい、ということです。