BCD(二進化十進数)は、人が読み書きする10進の各桁をそのまま4ビット単位で符号化する表現です。
小数点の位置や符号を別に管理することで、金額や測定値のような小数を誤差なく扱いやすくなります。
この記事では、基礎、仕組み、利点と注意点、そしてプログラミングでの変換方法までをやさしく解説します。
BCD(二進化十進数)とは
10進と2進の違い
私たちが日常で使うのは10進数ですが、コンピュータ内部では0と1の2進数が基本です。
例えば10進の13は2進では1101となります。
ここで大事なのは、2進表現は数全体を2進に変換するのに対し、BCDは10進の各桁を独立に4ビットで表すという点です。
つまり、同じ13でもBCDでは「1」と「3」をそれぞれ「0001」「0011」として並べます。
BCDの意味と基本
BCDはBinary Coded Decimalの略で、10進の1桁(0〜9)を4ビット(ニブル)に割り当てます。
結果として、0は0000、9は1001になります。
4ビットで表せる値は0〜15ですが、BCDでは10〜15は通常使いません。
以下は0〜9の対応表です。
| 10進の桁 | BCD(4ビット) | 16進表記 |
|---|---|---|
| 0 | 0000 | 0x0 |
| 1 | 0001 | 0x1 |
| 2 | 0010 | 0x2 |
| 3 | 0011 | 0x3 |
| 4 | 0100 | 0x4 |
| 5 | 0101 | 0x5 |
| 6 | 0110 | 0x6 |
| 7 | 0111 | 0x7 |
| 8 | 1000 | 0x8 |
| 9 | 1001 | 0x9 |
BCDは「各桁をそのまま持つ」ため、人間に見せる文字列への変換が簡単で、小数の誤差も生じません。
用途例
BCDは、人間が読む桁を崩したくない場面でよく使われます。
例えば、電卓、デジタル時計や計測機器の表示、金額や数量を扱う業務システム、シリアル通信での数値送受信などです。
桁の取り扱いが明確で、表示と計算を結び付けやすいことが理由です。
BCDの表現方法と仕組み
1桁=4ビット(ニブル)のルール
4ビット(ニブル)は0〜15を表せますが、BCDでは0〜9だけを使います。
10〜15の組み合わせは通常無効で、エラーチェックにも利用できます。
この「1桁=4ビット」という単純な対応が、扱いやすさの源です。
1バイトに2桁
1バイトは8ビットなので、4ビット×2桁を収められます。
これをパックドBCD(packed BCD)と呼びます。
上位ニブルに上位桁、下位ニブルに下位桁を入れます。
例えば、10進の45は「0100 0101」で、16進では0x45です。
1234ならニブル列は「0001 0010 0011 0100」で、16進では0x12 0x34となります。
1バイトに1桁
各桁を1バイトに入れる方法はアンパックドBCD(unpacked BCD)と呼ばれます。
多くの場合、上位ニブルは0000に固定し、下位ニブルに桁を入れます。
例えば12は0x01, 0x02となります。
桁ごとに1バイトなので読みやすい反面、容量は増えます。
BCDの表記例
表で、10進数とBCDの関係をいくつか示します(パックドBCD)。
| 10進数 | BCD(16進) | ビット列 | 備考 |
|---|---|---|---|
| 5 | 0x05 | 0000 0101 | 1バイトで1桁+前ゼロ |
| 45 | 0x45 | 0100 0101 | 1バイトで2桁 |
| 197 | 0x01 0x97 | 0000 0001 1001 0111 | 桁数が奇数なので先頭ニブルを0で埋める |
| 0073 | 0x00 0x73 | 0000 0000 0111 0011 | 先頭のゼロも桁として保持 |
10〜15のニブル値(1010〜1111)は通常のBCDでは無効です。
小数点と符号の扱い
BCD自体は「数字の並び」を持つだけで、小数点や符号は別で管理します。
よくある方法は次の通りです。
- 固定小数点: あらかじめ「小数点以下の桁数」を決めておきます。例えば「小数2桁」と決めたら、12345というBCDは「123.45」と解釈します。データには小数点を保存しないので、変換時に位置を差し込みます。
- 符号: プラスとマイナスは、別のフラグで持つか、最後のニブルを符号ニブルにする方式を使います。簡単な実装では「別フラグ」をおすすめします。符号ニブル方式では、末尾のニブルに0xC(+)や0xD(-)を入れる流儀がありますが、初心者はまずフラグ方式から始めると理解しやすいです。
BCDのメリット・デメリット
メリット
小数の誤差が出ないことが最大の利点です。
二進の浮動小数点では0.1などが正確に表せず丸め誤差が発生しますが、BCDは桁をそのまま持つため、金額や測定値のように桁が重要なデータを安全に扱えます。
また、文字列との相互変換が簡単で、表示や印字に強いです。
不正なニブルを検出しやすい点も品質管理に役立ちます。
デメリット
容量と速度の面で不利です。
2進整数なら同じビット数でより多くの値を表せますが、BCDは4ビットで1桁しか持てません。
加減算や乗除算も、CPUの2進演算に比べて処理が増えがちです。
また、10〜15のニブルは無効なので、入力チェックが欠かせません。
BCDが向くケース/向かないケース
金額、ポイント、在庫数、測定値など桁がそのまま意味を持つデータには向きます。
人に見せる値を頻繁に扱う機器やプロトコルとも相性が良いです。
一方で、統計計算やシミュレーションなど大量の数値演算や高速処理が必要な用途では、通常の2進整数や浮動小数点の方が適しています。
プログラミングでの使い方と変換
10進→BCDの変換手順
最もわかりやすいのは「文字列から作る」方法です。
各文字を数字に直し、その数字をニブルとして詰めるだけです。
- 10進の数値を文字列にします(例: “197”)。
- 1文字ずつ取り出し、’0’〜’9’の範囲か確認して数値化します。
- パックドBCDにする場合は、2桁ずつ上位ニブルと下位ニブルに詰めます。桁数が奇数なら、先頭に0ニブルを足して2桁に揃えます。
- アンパックドBCDにする場合は、各桁を1バイトに格納します(上位ニブルは0)。
例1(パックド): “197” → 桁は1,9,7 → 先頭を0で埋めて「0,1,9,7」→ 0x01 0x97 例2(アンパックド): “45” → 0x04, 0x05
数値から直接作る場合は、10で割った余りを順に取り出し(0〜9になる)、ニブルとして後ろから詰めます。
最後に並びを反転するか、先頭ゼロで桁合わせします。
BCD→10進の変換手順
保存されたBCDから10進の文字列や数値を得るには、ニブルを1つずつ取り出して数字に戻し、順に連結します。
- 各バイトから上位ニブル、下位ニブルを取り出します。
- ニブルが0〜9か検査します。10〜15なら不正データです。
- 0〜9なら対応する文字(‘0’〜’9’)に変換し、連結します。
- 必要であれば先頭のゼロを除去し、固定小数点なら小数点位置を挿入します。符号フラグもここで反映します。
0x12 0x34 → ニブル列は1,2,3,4 → “1234”
BCDの加算・繰り上がりの考え方
BCDでは、各桁を足して10以上になったら「6(0110)を加えて補正」し、繰り上がりを次桁に伝えるというルールを使います。
これはCPUの2進加算の結果をBCDとして正しい桁に直すためです。
39 + 28
- 下位桁: 9 + 8 = 17。10以上なので6を加えて17+6=23。結果の下位ニブルは7、1桁繰り上がり。
- 次桁: 3 + 2 + 繰り上がり1 = 6。10未満なのでそのまま。
→ 結果は67。
ポイントは、各桁を独立に処理し、補正が必要なら6を足すというシンプルな流れです。
減算や乗除算も考え方は似ていますが、初心者のうちは加算と繰り上がりから慣れると理解しやすいです。
桁数・ゼロ埋めの扱い
BCDは桁をそのまま持つため、保存領域の桁数を先に決めておくと実装が楽になります。
例えば「6桁フィールド」と決めたら、123は「000123」に左側ゼロ埋めしてからBCD化します。
パックドBCDなら0x00 0x01 0x23のようになります。
桁数が奇数のときは、パックドBCDでは先頭に0ニブルを足して2ニブルごとに揃えます。
表示する時は、用途に応じて先頭ゼロをそのまま見せるか、省くかを選びます。
固定小数点では、小数点以下の桁数を覚えておき、その位置に小数点を挿入します。
まとめ
BCDは、10進の各桁を4ビットで直接表すことで、小数の誤差なく、人に見せやすい数値処理を可能にする表現です。
パックドとアンパックドの基本、1桁=4ビットのルール、固定小数点や符号の扱いを押さえれば、金額や表示中心のアプリで確実に使えます。
変換は「文字列からニブルへ」「ニブルから文字列へ」という素直な手順で実装でき、加算は「10以上なら6を足して補正」という考え方を覚えるだけで十分です。
まずは小さな数で手を動かし、桁合わせやゼロ埋め、小数点の位置付けに慣れていくことが上達への近道です。
