学ぶ › トピック 6
数の表現:2 進数、8 進数、16 進数と各種コード
読了時間:約 7 分 · bitGateLab チーム
デジタル回路が理解できるのは 0 と 1 だけですが、私たちは数量、符号、表示器の数字、エンコーダの位置などを表現しなければなりません。この記事では、位取り記数法のしくみ、10 進数・2 進数・8 進数・16 進数の相互変換、2 の補数による負の数の表現、そして電子回路でよく使われる二つのコード、BCD とグレイコードを学びます。
位取り記数法
基数 b の位取り記数法では、各桁の数字に、その位置に応じた b のべき乗を掛けます。位置は右端を 0 として数えます。10 進数の 347 は 3·102 + 4·101 + 7·100 です。ほかの基数でも同じです。
- 2 進数(基数 2):数字は 0 と 1 で、ビットと呼びます。重みは 1、2、4、8、16、32、64、128… です。
- 8 進数(基数 8):数字は 0 から 7 です。8 進数の 1 桁は 3 ビットに相当します。
- 16 進数(基数 16):数字は 0 から 9 と A から F です(A = 10、B = 11、C = 12、D = 13、E = 14、F = 15)。16 進数の 1 桁は 4 ビットに相当します。
混同を避けるため、基数は添字(10102、178、3F16)か、0b や 0x のような接頭辞で示します。
基数の変換
任意の基数から 10 進数へ
各桁の数字にその重みを掛けて、足し合わせます。たとえば 2F316 = 2·256 + 15·16 + 3·1 = 512 + 240 + 3 = 755 です。
10 進数から 2 進数へ
2 で繰り返し割り、余りを書き留めます。2 進数は下から上へ読みます(最後の余りが最上位ビットです)。別の方法として、引くことのできる最大の 2 のべき乗を引く操作を繰り返すこともできます。
2 進数、8 進数、16 進数の間の変換
8 = 23、16 = 24 なので、10 進数を経由する必要はありません。右端から 3 ビットずつ(8 進数)、または 4 ビットずつ(16 進数)に区切り、必要なら左側に 0 を補います。
例 1:156 を 2 進数、8 進数、16 進数に変換する。
- 割り算を繰り返します。156/2 = 78 余り 0、78/2 = 39 余り 0、39/2 = 19 余り 1、19/2 = 9 余り 1、9/2 = 4 余り 1、4/2 = 2 余り 0、2/2 = 1 余り 0、1/2 = 0 余り 1。
- 余りを下から上へ読むと、156 = 100111002 です。検算:128 + 16 + 8 + 4 = 156。
- 8 進数:10 011 100 → 010 011 100 → 2 3 4。結果は 2348 です(2·64 + 3·8 + 4 = 156)。
- 16 進数:1001 1100 → 9 C。結果は 9C16 です(9·16 + 12 = 156)。
負の数:2 の補数
ビット数が n のレジスタには「マイナス」記号を置く場所がないので、取り決めを使います。ほぼすべてのプロセッサで使われているのが 2 の補数です。最上位ビットが負の重み −2n−1 を持ち、ほかのビットは正の重みのままです。8 ビットなら範囲は −128 から +127、4 ビットなら −8 から +7 です。
ある数の負の値を求めるには、次のようにします。
- 正の数を、すべてのビットを使って書きます。
- 各ビットを反転します(これが 1 の補数です)。
- 1 を足します。
この方式の利点はとても大きく、加算も減算も同じ加算回路で実行でき、符号のための特別な論理が要りません。ゼロは一つだけ(00000000)で、最上位ビットを見れば負の数かどうかがすぐにわかります。
例 2:−45 を 8 ビットで表し、25 + (−12) を計算する。
- 45 = 00101101。反転すると 11010010。1 を足すと 11010011 = −45。
- 重みで検算:−128 + 64 + 16 + 2 + 1 = −45。
- 次に 25 + (−12) です。25 = 00011001。12 = 00001100、反転して 11110011、1 を足して 11110100 = −12。
- 加算:00011001 + 11110100 = 1 00001101。ビット 8 から出るキャリーは捨てます。
- 結果:00001101 = 13。正しい答えです。
BCD コード
いわゆる BCD(2 進化 10 進数、8421 コード)では、10 進数の各桁を別々に 4 ビットで表します。たとえば 395 は 0011 1001 0101 と書きます。これは 395 を 2 進数に変換したもの(1100010112)とは違います。BCD のほうがビットを多く使いますが、各グループを、割り算なしでそのまま 7 セグメント表示器のデコーダに送れます。コード 1010 から 1111 は BCD では無効です。設計では、これらの組み合わせはカルノー図でドントケア条件として扱うのが普通です。
グレイコード
もう一つのグレイコードでは、ある値から次の値に移るとき、1 ビットしか変化しません。通常の 2 進数では、7(0111)から 8(1000)に移るときに四つのビットが同時に変化します。ちょうどその切り替わりの瞬間にセンサが読み取ると、一瞬だけ、途中のどんな値でも見えてしまう可能性があります。グレイコードならこの誤りは起こりません。そのため、位置エンコーダ、異なるクロックの間をまたぐカウンタ、そしてカルノー図の見出しに使われます。
- 2 進数からグレイコードへ:最上位ビットはそのまま写します。それ以降の各ビットは、対応する 2 進ビットと、その左隣の 2 進ビットの XOR です。式で書くと、g = b ⊕ (b を右に 1 桁シフトしたもの)。
- グレイコードから 2 進数へ:最上位ビットはそのまま写します。それ以降の各 2 進ビットは、直前に求めた 2 進ビットと、その位置のグレイビットの XOR です。
| 10 進 | 2 進 | グレイ | 10 進 | 2 進 | グレイ |
|---|---|---|---|---|---|
| 0 | 0000 | 0000 | 8 | 1000 | 1100 |
| 1 | 0001 | 0001 | 9 | 1001 | 1101 |
| 2 | 0010 | 0011 | 10 | 1010 | 1111 |
| 3 | 0011 | 0010 | 11 | 1011 | 1110 |
| 4 | 0100 | 0110 | 12 | 1100 | 1010 |
| 5 | 0101 | 0111 | 13 | 1101 | 1011 |
| 6 | 0110 | 0101 | 14 | 1110 | 1001 |
| 7 | 0111 | 0100 | 15 | 1111 | 1000 |
例 3:2 進数 1011 をグレイコードに変換し、元に戻す。
- 最初のビットを写します:1。
- 1 ⊕ 0 = 1、0 ⊕ 1 = 1、1 ⊕ 1 = 0。グレイコード = 1110。
- 元に戻します。最初のビットを写して b3 = 1。続いて b2 = 1 ⊕ 1 = 0、b1 = 0 ⊕ 1 = 1、b0 = 1 ⊕ 0 = 1。2 進数 = 1011。
表でも、10 進数の 11 はグレイコード 1110 になっていて、一致します。
よくある間違い
- 8 進数や 16 進数に変換するとき、左からビットを区切る。必ず最下位ビットから区切ります。
- 2 の補数の「+1」を忘れる。反転するだけでは 1 の補数になり、ゼロが二つあるうえ、範囲も変わります。
- 符号付きのレジスタなのに、11010011 を 211 と解釈する。同じビットパターンでも、符号なしなら 211、符号付きなら −45 です。どちらになるかは取り決め次第です。
- BCD と 2 進数を混同する。25 は BCD では 0010 0101 ですが、2 進数では 11001 です。
- グレイコードを 2 進数に変換するとき、直前に計算した 2 進ビットではなく、隣のグレイビットと XOR をとる。
シミュレータで試してみよう
入力と出力をいくつか使えば、これらの表現を「実際に動かして」確かめられます。グレイコードへの変換も XOR ゲートで確認できます。
- 入力を四つ置いてビット b3〜b0 とし、値を見るための表示器か LED 四つを接続します。
- XOR ゲートを三つ追加します。g2 = b3 ⊕ b2、g1 = b2 ⊕ b1、g0 = b1 ⊕ b0 とし、b3 はそのまま g3 につなぎます。
- 入力を 0000 から 1111 まで切り替え、ある値から次の値に移るときにグレイコードのビットが一つしか変化しないことを、出力で確かめます。
- 回路の真理値表を生成し、この記事の表と比べます。
練習問題
- 110101102 を 16 進数と 10 進数に変換してください。
解答
1101 0110 = D616 = 13·16 + 6 = 214。
- 200 を 2 進数と 16 進数に変換してください。
解答
200 = 128 + 64 + 8 = 110010002 = C816。
- −100 を 8 ビットの 2 の補数で表してください。
解答
100 = 01100100。反転して 10011011。1 を足して 10011100。検算:−128 + 16 + 8 + 4 = −100。
- 10 進数の 6 を 4 ビットのグレイコードに変換し、BCD の 0111 0010 を 10 進数に変換してください。
解答
6 = 0110。グレイコード:0、0 ⊕ 1 = 1、1 ⊕ 1 = 0、1 ⊕ 0 = 1 → 0101。BCD の 0111 0010 は 72 です。
回路がこれらの数をどのように足したり引いたりするかは、2 進加算器で学びましょう。