bitGateLab Digital · 学ぶ
日本語
シミュレータを開く

学ぶ › トピック 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 です。ほかの基数でも同じです。

混同を避けるため、基数は添字(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 進数に変換する。

  1. 割り算を繰り返します。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。
  2. 余りを下から上へ読むと、156 = 100111002 です。検算:128 + 16 + 8 + 4 = 156。
  3. 8 進数:10 011 100 → 010 011 100 → 2 3 4。結果は 2348 です(2·64 + 3·8 + 4 = 156)。
  4. 16 進数:1001 1100 → 9 C。結果は 9C16 です(9·16 + 12 = 156)。

負の数:2 の補数

ビット数が n のレジスタには「マイナス」記号を置く場所がないので、取り決めを使います。ほぼすべてのプロセッサで使われているのが 2 の補数です。最上位ビットが負の重み −2n−1 を持ち、ほかのビットは正の重みのままです。8 ビットなら範囲は −128 から +127、4 ビットなら −8 から +7 です。

ある数の負の値を求めるには、次のようにします。

  1. 正の数を、すべてのビットを使って書きます。
  2. 各ビットを反転します(これが 1 の補数です)。
  3. 1 を足します。

この方式の利点はとても大きく、加算も減算も同じ加算回路で実行でき、符号のための特別な論理が要りません。ゼロは一つだけ(00000000)で、最上位ビットを見れば負の数かどうかがすぐにわかります。

例 2:−45 を 8 ビットで表し、25 + (−12) を計算する。

  1. 45 = 00101101。反転すると 11010010。1 を足すと 11010011 = −45。
  2. 重みで検算:−128 + 64 + 16 + 2 + 1 = −45。
  3. 次に 25 + (−12) です。25 = 00011001。12 = 00001100、反転して 11110011、1 を足して 11110100 = −12。
  4. 加算:00011001 + 11110100 = 1 00001101。ビット 8 から出るキャリーは捨てます。
  5. 結果:00001101 = 13。正しい答えです。
オーバーフロー:同じ符号の二つの数を足して、結果が逆の符号になったら、その結果は使えるビット数に収まっていません。たとえば 8 ビットでは 100 + 50 = 01100100 + 00110010 = 10010110 となり、これは 2 の補数では 150 ではなく −106 を表します。符号の異なる数どうしの加算では、オーバーフローは決して起こりません。

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)に移るときに四つのビットが同時に変化します。ちょうどその切り替わりの瞬間にセンサが読み取ると、一瞬だけ、途中のどんな値でも見えてしまう可能性があります。グレイコードならこの誤りは起こりません。そのため、位置エンコーダ、異なるクロックの間をまたぐカウンタ、そしてカルノー図の見出しに使われます。

10 進2 進グレイ10 進2 進グレイ
000000000810001100
100010001910011101
2001000111010101111
3001100101110111110
4010001101211001010
5010101111311011011
6011001011411101001
7011101001511111000

例 3:2 進数 1011 をグレイコードに変換し、元に戻す。

  1. 最初のビットを写します:1。
  2. 1 ⊕ 0 = 1、0 ⊕ 1 = 1、1 ⊕ 1 = 0。グレイコード = 1110。
  3. 元に戻します。最初のビットを写して b3 = 1。続いて b2 = 1 ⊕ 1 = 0、b1 = 0 ⊕ 1 = 1、b0 = 1 ⊕ 0 = 1。2 進数 = 1011。

表でも、10 進数の 11 はグレイコード 1110 になっていて、一致します。

よくある間違い

シミュレータで試してみよう

入力と出力をいくつか使えば、これらの表現を「実際に動かして」確かめられます。グレイコードへの変換も XOR ゲートで確認できます。

  1. 入力を四つ置いてビット b3〜b0 とし、値を見るための表示器か LED 四つを接続します。
  2. XOR ゲートを三つ追加します。g2 = b3 ⊕ b2、g1 = b2 ⊕ b1、g0 = b1 ⊕ b0 とし、b3 はそのまま g3 につなぎます。
  3. 入力を 0000 から 1111 まで切り替え、ある値から次の値に移るときにグレイコードのビットが一つしか変化しないことを、出力で確かめます。
  4. 回路の真理値表を生成し、この記事の表と比べます。

練習問題

  1. 110101102 を 16 進数と 10 進数に変換してください。
    解答

    1101 0110 = D616 = 13·16 + 6 = 214。

  2. 200 を 2 進数と 16 進数に変換してください。
    解答

    200 = 128 + 64 + 8 = 110010002 = C816。

  3. −100 を 8 ビットの 2 の補数で表してください。
    解答

    100 = 01100100。反転して 10011011。1 を足して 10011100。検算:−128 + 16 + 8 + 4 = −100。

  4. 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 進加算器で学びましょう。