このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ

  • 追加された行はこの色です。
  • 削除された行はこの色です。
*目次 [#te5d9555]

#contents


*はじめに [#da45f621]

 コンピュータ内部の数値表現の基本は2進数である。しかしながら、10進数と2進数との間の誤差の回避や、データ入力時には10進数を使うことなどから、10進数のままデータを処理するほうが都合がよいこともある。そうした場合に使われる表現方法として、BCDコード・ゾーン10進数・パック10進数がある。 
 コンピュータは数を2進数で表す。しかし、人間がキーボードから入力した数字が、コンピュータの中ですぐに2進数に変換されるわけではない。なぜならばキーボードの数字は一種の文字だからである。~
 また、10進数と2進数との間の誤差の回避や、データ入力時には10進数を使うことなどから、10進数のままデータを処理するほうが都合がよいこともある。~
 そうした場合に使われる表現方法として、BCDコード・ゾーン10進数・パック10進数がある。

 2進数であれば4ビットで0〜15を表現可能であるが、BCDは2進化10進数であるため4ビットで0〜9までの数値を表現する。

[例]89という数字をキーボードで入力したら、すぐに1011001になるわけではなく、まず10進数を1桁ずつ2進数にする。即ち8と9をそれぞれ2進数にする。すると、1000と1001になる。これを連結して「10001001」にする。これをBCDコードという。 ◇

[補講]実際にはBCDコードが使われるわけではなく、「BCDコードを含むコード」(「BCDコード+α」という意味)になる。このBCDコードを含むコードというのがゾーン10進数やパック10進数である。 ◇


*BCDコード [#j6a2461e]

 文字データや10進数との対応が取りやすいように、10進数の0〜9に対応した4ビットの2進数で10進数の各桁を表現する方法を''BCDコード(Binary Coded Decimal code:2進化10進コード)''という。

 BCDコードでは、4ビットを単位として0000〜1001(2進数)までの0〜9(10進数)に対応させて、1011〜1111は使用しない。

 10真数の桁数に合わせて2進数の桁数も変化する可変長形式の表現である。


*ゾーン10進数 [#l6670d72]

 ''ゾーン10進数(アンパック10進数)''とは、10進数の1桁を1バイト(=8ビット)で表現する。
 BCD同士の演算(例えば加算など)のときは桁上がり値を適切に確保する必要がある。これを考慮して、8ビットで1桁の10進数(0〜9)を表現するBCDがある。これアンパック形式BCDという。これに対して、4ビットで1桁の10進数を表現するBCDをパック形式BCDという。

 ''ゾーン10進数(アンパック10進数、アンパック形式BCD)''とは、10進数の1桁を1バイト(=8ビット)で表現する。

 上位4ビットを''ゾーン部''、下位4ビットを''整数部''という。~
 整数部はBCDコードと同じ表現を用いる。~
 ゾーン部はJISコード形式では(0011)SUB{2};、汎用コンピュータで用いられるEBCDIC形式では(1111)SUB{2};を割り当てる。これは0〜9の値をそのままそれぞれコード形式の'0'〜'9'に対応させることになるので、10進数値と文字コードの対応が取れて都合がよい。

 ただし、最下位桁のゾーン部は符号部として使用する。一般に0と正の場合は(1100)SUB{2};、負の場合は(1101)SUB{2};を割り当てる。

例1:JISコード形式の「123」と「-123」

#img(http://s-akademeia.sakura.ne.jp/main/image9/zone1.jpg)
#img(,clear)

#img(http://s-akademeia.sakura.ne.jp/main/image9/zone2.jpg)
#img(,clear)

例2:EBCDICコード形式の「123」と「-123」

#img(http://s-akademeia.sakura.ne.jp/main/image9/zone3.jpg)
#img(,clear)

#img(http://s-akademeia.sakura.ne.jp/main/image9/zone4.jpg)
#img(,clear)


**ゾーン10進数とJISコードの関係 [#b28b2920]

 例えば90をBCDコードにすると、「1001 0000」になる。一方、ゾーン10進数では9の「1001」に「0011」という数字列を頭につけて、10進数の1桁の9を「0011 1001」と表す。つまり、ゾーン10進数では各桁ごとに「0011」を付けるわけである。実は、これはJISコードそのものなのである。

 8ビットのJISコードでは、0011の列、即ち3の列が数字になっている。JISコード表を実際に確認してもらえればわかると思うが、3列0行目〜3列9行目が0〜9に対応している。

 つまり、9という文字を指定するのに、39という数字、2進数でいえば「0011 1001」を使う。この8ビットコードが「0011 1001」の下4桁がBCDということになる。

 また、JISには他にEBCDIC(拡張2進化10進コード)というコードもある。このときは、頭に「1111」を付ける。

 以上のように頭に付ける「0011」や「1111」のことを''ゾーン部''という。


*パック10進数 [#fd98b98d]

 ''パック10進数表記法''とは、BCD(2進化10進数)コードを使い、10進数の各桁の値を4ビットの2進数で表現する方法である。そのため、1バイト(=8ビット)に10進数の2桁を記憶できる。

 また、符号は最下位バイトの下位4ビットに入れる。正負をどのようなビットの並びで表すかは、システムによって異なる。

 パック10進数表記法の長さは、バイト単位で決定されるので、6桁であっても7桁であっても4バイト(=32ビット)分必要になる。-9,999,999から+9,999,999まで(10進数)の数値を扱うことができる。

例:数値の部分が6桁の符号付き10進数「-123456」だと次のようになる。

#img(http://s-akademeia.sakura.ne.jp/main/image9/pack.jpg)
#img(,clear)

**ゾーン10進数とパック10進数の比較 [#ff720d1c]

 パック10進数はゾーン10進数に比べて、使用するバイト数が小さくてすみ、ゾーン部がないため演算が可能であるというメリットがある。必要とするバイト数は、ゾーン10進数が10進数の桁数分のバイト数が必要である。一方、パック10進数では10進数が偶数桁か奇数桁かで変化する。

[1]偶数桁n桁の場合

&mimetex("\frac{n}{2}+1");

[2]奇数桁n桁の場合

&mimetex("\frac{\( n+1 \)}{2}");

 ガウスのfloor funcitonを用いると、2つの式を次のようにひとつに統一できる。

&mimetex("\[ \frac{n}{2} \] +1");


 データの入出力には文字コードと同じ1バイト単位のゾーン10進数が便利である。一方、演算時には10進演算か2進の固定小数点演算か浮動小数点演算の適する形式に変換される。

#img(http://s-akademeia.sakura.ne.jp/main/image9/zone5.jpg)
#img(,clear)

*プログラム言語とBCD [#h5d2ded9]

**asm(8086) [#m926ef47]

|命令|意味|h
|AAA|アンパック形式BCD値同士を加算(ADD)した結果をBCD表現に戻す。|
|AAS|アンパック形式BCD値同士を減算(SUB)した結果をBCD表現に戻す。|
|AAM|アンパック形式BCD値同士の乗算(MUL)した結果をBCD表現に戻す。|
|AAD|アンパック形式BCD値同士の除算(DIV)を実行する前に、非除数(分子)をバイナリに変換して、BCD計算が正しく行われるように準備する。|
|DAA|パック形式BCD値同士の加算(ADD)した結果をBCD表現に戻す。|
|DAS|パック形式BCD値同士を減算(SUB)した結果をBCD表現に戻す。|

[補講][[サンプルプログラム1:https://github.com/ipusiron/sample/blob/master/asm/8086/Calculation/tst_aaa.asm]]、[[サンプルプログラム2:https://github.com/ipusiron/sample/blob/master/asm/8086/Calculation/tst_aam.asm]] ◇

*参考文献 [#zeff0ecd]

-『2001秋 徹底解説 基本情報技術者本試験問題』
-『平成16年度【秋期】基本情報技術者合格教本』
-『超図解mini 基本情報技術者試験 平成19年度版』
-『情報処理技術者試験 SUPER記憶術SERIES まんがでわかる情報処理の基本 デジタル数学編』
-『高級プログラマのためのアセンブラ入門』