この章の概要です。
我々は普段の生活で数を表記するとき、0~9 までの 10種類の数を使っています。これは 10進法 (decimal system、decimal notation) と呼ばれる表記方法です。また、10進法で表記された数を 10進数 (decimal number) と呼びます。
10進法では、0 から順番に 1 ずつ大きくしていくと、10 のところで桁が増えます。これが「10進」という言葉の意味合いで、10 になると進む(桁が変わる)ということです。
10進法では、数を 10 のべき乗と、10種類の数字(0~9) を使って表現します。たとえば、345 という数は、「102 * 3 + 101 * 4 + 100 * 5」と考えればよいです(ある正の数の 0乗はつねに 1 です)。
小数点以下の値も同様に考えられます。たとえば、345.67 であれば、「102 * 3 + 101 * 4 + 100 * 5 + 10-1 * 6 + 10-2 * 7」のことです。10-1 とは、10分の1 (0.1) のこと、10-2 とは 100分の1 (0.01) のことです。
先ほどの 10進数の話の中で、「10」のべき乗とか、「10」種類の数字といったように、10 という値が現れました。この数を、基数 (radix、base) といいます。
基数は 10以外であっても構いません。コンピュータの世界では、基数が 2、8、10、16 の数がよく用いられます。基数を n と表現すると、その場合の表記法を n進法と表現します。また、n進法で表記された数を n進数と表現します。
コンピュータでは 2進数 (binary number) が非常に重要です。なぜなら、コンピュータはデータを 2進数で表現するからです。日頃、コンピュータを利用していてもそう感じることは滅多にありませんが、コンピュータの側では 2進数、人間に見える部分には分かりやすいように(通常は)10進数が使われているのです。
2進数の数値は、0、1、10、11、100 … のように増えていきます。つまり、2 のところで桁が変わります(2 で次の桁に進む)。
「10進数」のところで見たように、基数が 2 であることの意味は、数を 2 のべき乗と、2種類の数字(0~1) を使って表現するということです。たとえば、2進数の 1001.11 という数は、「23 * 1 + 22 * 0 + 21 * 0 + 20 * 1 + 2-1 * 1 + 2-2 * 1」であることを意味しています。「8 + 0 + 0 + 1 + 0.5 + 0.25」なのでこれは 10進数の「9.75」です。
このように、2進数の「1001」と、10進数の「9」は同じ値です。つまり異なる表記方法を用いているだけであって、これらは同じ1つの「数」なのです。表記方法の話をしているのか、数そのものがいくつであるのかの話をしているのかは区別しておきましょう。
なお、2進数の「1000」を「せん」と読んでしまうと、10進数の「1000」のことと思われてしまう可能性があります。2進数の「1000」は「いちぜろぜろぜろ」のように呼ぶのが確実です。
はじめにコンピュータでは 2進数を使ってデータを表現すると書きました。したがって、コンピュータがあつかうデータの最小は、2進数で1桁分の大きさということになります。この最小単位のことをビット (bit) といいます。
2進数1桁で表現できるデータは 0 か 1 のいずれかだけですから、1ビットで表現できるデータは 2通りだけです。たとえば「YES か NO」というデータは 1ビットだけで表現可能ということになります。nビットあれば 2^n 通りのデータを扱えます。
基数が n の数を、異なる基数 m の数に変換することを基数変換 (radix conversion、base conversion) といいます。
たとえば 10進数を 2進数に変換するには、以下の手順を行います。
10進数の 93 なら以下のようになります。
2)93
2)46・・・1
2)23・・・0
2)11・・・1
2) 5・・・1
2) 2・・・1
2) 1・・・0
0・・・1
書き出された余りの部分を下から上に向かって読み取ると、結果は「1011101」です。
この方法は、元になる数が 10進数でさえあれば、変換先が何進数であっても同じように使えます。たとえば、5進数に変換するのなら 5 で割ることを繰り返します。
5)93
5)18・・・3
5) 3・・・3
0・・・3
結果は「333」です。
小数点以下がある場合は、小数点以下の部分に注目して以下の操作を行います。10進数から 2進数の場合なら次のようになります。
たとえば、10進数の 0.375 なら以下のようになります。
0.375 ×2=0.75
0.75 ×2=1.5
0.5 ×2=1.0
書き出された整数部分を上から下に向かって読むと「011」です。この頭の部分に「0.」を補った「0.011」が変換結果になっています。
これも 元になる数が 10進数でさえあれば、変換先が何進数であっても同じように使えます。
たとえば、5進数に変換するのなら 5 で掛けることを繰り返します。10進数の「0.744」を 5進数に変換してみます。
0.744 ×5=3.72
0.72 ×5=3.6
0.6 ×5=3.0
書き出された整数部分を上から下に向かって読むと「333」です。この頭の部分に「0.」を補った「0.333」が変換結果になっています。
次に、2進数から 10進数へ変換する方法ですが、これは「2進数」のところで見たとおりです。2進数の各桁は「2x * (0 または 1)」のことなので、ここから計算できます。
たとえば 2進数の「1011101」という数は、「26 * 1 + 25 * 0 + 24 * 1 + 23 * 1 + 22 * 1 + 21 * 0 + 20 * 1」です。したがって「64 + 16 + 8 + 4 + 1」ですから、その結果は 93 です。
小数点以下があっても考え方は同じです。2進数の「101.11」を 10進数に変換する場合なら、「22 * 1 + 21 * 0 + 20 * 1 + 2-1 * 1 + 2-2 * 1」なので、「4 + 1 + 0.5 + 0.25」=「5.75」となります。
この方法は、10進数へ変換するのであれば、変換元が何進数であっても同じように使えます。前の項と同様に、5進数で実験しましょう。5進数の「333」を 10進数に変換します。
5進数の「333」は、「52 * 3 + 51 * 3 + 50 * 3」ですから、「75 + 15 + 3」となり、その結果は 93 です。
8進数 (octal number) は、8進法 (octal system、octal notation) で表記された数です。8進法では「0~7」までの合計 8種類の数字で数を表記します。7 の次で桁が増えるので、「…6、7、10、11…」と増えていきます。
16進数 (hexadecimal number) は、16進法 (hexadecimal system、hexadecimal notation)で表記された数です。16進法では「0~9」と「A~F」の合計 16種類の数字と文字を使って表記します。アルファベットの部分は、大文字でも小文字でも構いません。
16進法では、「…7、8、9」と増えていった数は、次に「A、B、C、D、E、F」と増えます。10進数でいえば、A が 10、B が 11、F が 15 を意味しています。F の次で桁が増えて、16進数の「10」になります。
よく登場する 2・8・10・16進数の対応表を載せておきます。
2進数 | 8進数 | 10進数 | 16進数 |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 1 | 1 | 1 |
10 | 2 | 2 | 2 |
11 | 3 | 3 | 3 |
100 | 4 | 4 | 4 |
101 | 5 | 5 | 5 |
110 | 6 | 6 | 6 |
111 | 7 | 7 | 7 |
1000 | 10 | 8 | 8 |
1001 | 11 | 9 | 9 |
1010 | 12 | 10 | A |
1011 | 13 | 11 | B |
1100 | 14 | 12 | C |
1101 | 15 | 13 | D |
1110 | 16 | 14 | E |
1111 | 17 | 15 | F |
2進数から 16進数に変換する場合、2進数4桁分が 16進数1桁分に当たる(24 == 16)ので、下位から 4桁ずつに区切って、足りない部分に 0 を補います。「1101100」であれば、「0110」「1100」になります。あとはそれぞれを 16進数に変換すればよく(対応表を参照)、簡単に「6」と「C」が得られます。2進数から 8進数なら 3桁ずつに区切って同じことをすればいいです。
反対に、16進数から 2進数であれば、「6C」の 1桁ずつを 2進数に変換して並べればいいです。「6」は 2進数では「110」、「C」は 2進数では「1100」ですから(対応表を参照)、結果は「1101100」です。
n と m が分かりづらい基数の場合であっても、n進数から 10進数の変換と 10進数から n進数の変換、を利用して、次の手順を踏めば変換できます。
2進数の 1101100 を 16進数に変換してみましょう。まずは 10進数に変換します。
「26 * 1 + 25 * 1 + 24 * 0 + 23 * 1 + 22 * 1 + 21 * 0 + 20 * 0」となり、「64 + 32 + 8 + 4」となるので、結果は 108 です。
10進数の 108 が得られたので、今度は 16進数への変換作業を行います。
16)108
16) 6・・・12
0・・・6
余りを逆方向から読むと「6 12」ですが、16進数なので「12」は「C」です。したがって、結果は「6C」です。
Windows の標準ツールである「電卓」を使うと、2進数、8進数、10進数、16進数のあいだでの変換を簡単に行えます。
方法は、「Windows編>電卓で基数変換する」を参照してください。
Amazon.co.jp へのリンクはアフィリエイトリンクです。
リンク先で商品を購入されると、Programming Place
管理者に紹介料が支払われます。
C言語編第18章から切り出してくる形で新規作成。
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |