misc.log

日常茶飯事とお仕事と

2年目若手向けにEBCDICとBCD記法について説明したときの資料

古いやりとりを掘り返していて見つけたメッセージを残しておきます(発掘日:2021/10/5)。

相手は新卒で入って2年目。専門教育なし。2年目でこんなことをやる羽目になるとか可哀想すぎる。客先で動いていたもののリプレースに関するもので、一部、その場の状況が判らないと理解できない話が混じってますが、記録として残しておきます。

BCD記法

数字の計算誤差をなくすために1ケタ1文字で数値を保持する記録方法。データベースのNumeric型とかDecimal型がこれです。「12」を二進表記すると「1100」ですが、BCDでは「1」「2」それぞれを二進数で表し、「0001 0010」となります。

※整数は良いのですが小数を二進数表記すると誤差が出るので、この形式で、演算処理も 人間が筆算するかのように桁単位で行えば誤差が出ない、という考え方です。

ゾーンBCD記法

今のコンピューターはデータを8ビット単位で処理した方が楽なので、上記のBCDの上位4ビットにダミー値を入れて無理やり1ケタ8ビットで表すようにしたもの。EBCDICコードの場合、上位に「1111(16進でF)」を足す。「12」の場合「11110001 11110010」→「F1 F2」となる。

ゾーンBCDと符号

ゾーンBCDでマイナス値を表すために、苦肉の策として「末尾1ケタの上位4ビットに符号を埋める」ということにしたようです。そのルールが、EBCDICコードの場合

  • プラスの場合は「1100」(16進でC)
  • マイナスの場合は「1101」(16進でD)

結果、

  • 「+12」の場合「11110001 11000010」→「F1 C2」となる。
  • 「-12」の場合「11110001 11010010」→「F1 D2」となる。


※ただし、AnyTranと実データを見るに、どうやら「F1 F2」の場合も「+12」のようですね…

実数表記

誤差をなくすためのBCDなので、小数表記もできないといけません。その方法として、BCD表記の「何桁目までが小数」というルールを設けて小数化する「仮想実数」方式があるようです。たとえば下2桁が小数と決まっている場合、「5000」は「50.00」となります。

※今回、どうも下2桁が小数というルールのようです。日食協フォーマットの委細をしらべれば わかるかもしれません……

AnyTranの謎ロジックの意味

上記の内容は「EBCDICコードのゾーンBCD表記された数字」という、データ型が決まっている場合の話ですが、これを「EBCDICコードの数字文字」として読んでしまうと、たとえば12は「F1 C2」→「1 B」となってしまいます。この状態から数字に戻そうと思うと、謎ロジックの出番になります。末尾が「B」だったら「2」に置き換えて文字列結合。
それを数値変換して、プラスの値として扱えば「+12」というわけですね。

おそらくですが、AnyTranでEBCDICの数値型(仮想実数)指定すれば自動的に数値として読んでくれることを知らなかった人が文字として定義してしまい、苦肉の策で自力数値化を行った残骸ロジックと推測されます。

よって、マイナス値を実際に読ませてみてきちんと読めれば、謎ロジックは不要かと。