技術とか戦略とか

証券レガシーシステムを8年いじってから転職した普通の文系SEによるブログ。技術のみではなく趣味の戦略考察についても。

COBOLにおけるパック10進数(COMP-3)のデータの持ち方

パック10進数は色々なサイトで説明されていますが、今回の記事では正確さは置いといて実務で必要な知識をわかりやすく説明します。
 
【パック10進数とは】
パック10進数は、1バイトで数値2桁を表現する形式です。
バイト数を削減できる、16進で文字コードを見た時に見やすい、という利点があります。
 
COBOLでは、ワークの定義時に「COMP-3」をつけることでパック10進数形式になります。
 
・通常の定義の場合
03  NUM   PIC S9(3).
 
・パック10進数で定義する場合
03  NUM   PIC S9(3) COMP-3.
 
※「9」は数値タイプ。また「S」を定義すると符号を扱えるようになる。
 
【16進数にした場合の文字の見え方】
1バイトの文字を16進数で表現すると"00"(LOW-VALUE)~"FF"(HIGH-VALUE)になります。
1バイトにつき0~Fの範囲の文字が2つくっついたような形になります。
 
「PIC 9(3)」で定義したワークに「123」を代入すると、16進数では以下のように見えます。
文字コードEBCDICの場合)
F1 F2 F3
EBCDICの場合、「1」は16進数で「F1」、「2」は「F2」、「3」は「F3」なので、こうなります。
 
それに対して、「PIC 9(3) COMP-3」でワークが定義されていると以下のようになります。
12 3C
この例を見れば、「1バイトで数値2桁を表現する」というのが直感的に理解できると思います。
 
ちなみに、COMP-3のワークの一番後ろの「C」は、プラスを表しています。
マイナスの値の場合はこれが「D」になります。
つまり、「PIC S9(3) COMP-3」で定義したワークに「-123」を代入するとこうなります。
12 3D
 
【パック10進数のワークのバイト数】
結論から言うと以下です。
 (数値の桁数/2)+0.5 ※小数点以下切り上げ
 
「数値の桁数/2」は「1バイトで数値2桁を表現する」を表しています。
「+0.5」は後ろに付与される符号(C/D)を表しており、これが0.5バイトに相当します。
 
「小数点以下切り上げ」は、1バイトに満たない文字が現れた場合のゼロ埋めを示しています。
例えば、「PIC 9(4) COMP-3」で定義したワークに「1234」を代入すると以下になります。
01 23 4C
前に「0」を入れないと1バイトに満たない箇所が現れてしまうので、前に「0」を入れて1バイト単位にしています。
 
【パック10進数を扱う時の注意点】
9タイプはXタイプ(文字タイプ)と16進数にした時の表現が同じなので、9タイプからXタイプへのMOVEは上手く行きます。
しかし、9 COMP-3タイプとXタイプは表現が異なるので、9 COMP-3タイプからXタイプへMOVEすると文字化けしたり異常終了したりする原因になります。
なお、9 COMP-3タイプから9タイプへのMOVEは自動的に変換されるので問題ありません。
 
【正確な情報が知りたい場合】
以上の説明はわかりやすさ重視の説明なので、正確な情報が知りたい場合はWikipedia等を見た方が良いです。
 
パック10進数 - Wikipedia

https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%83%E3%82%AF10%E9%80%B2%E6%95%B0
 
なお、最近は出題がないようなのですが、かつては情報処理技術者試験でも出題されるテーマでした。
時代の流れ的に出題頻度は低くなるはずですが、忘れた頃に出題される可能性もあるので、念のためリンクを貼っておきます。
 
パック10進数 [徹底研究!情報処理試験]

http://mt-net.vis.ne.jp/ADFE_mail/0333.htm

---------------------
情報処理技術者試験対策 目次

https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM