はじめに
膨大な数値データを扱うエンタープライズシステムでは、処理効率と互換性を両立させる仕組みが求められています。その中で、パック10進数は、メインフレームが企業システムの中心であった時代から長年に渡り採用されてきた堅牢なフォーマットです。この記事ではデータ変換ツールDTRII 1 を利用して数値データをパック10進数に変換してみます。
パック10進数
パック10進数(Packed Decimal)は、コンピュータ内部で10進数を効率よく正確に扱うためのデータ表現方式です。パック10進数では1バイトで2桁の10進数を表現します。メインフレームやCOBOLなどで利用されます。浮動小数点ではなく、10進数ベースで演算するため、計算結果が正確であり、金融や会計などの丸め誤差を許容できない業務で有効です。
コンピュータはデータを0と1の2進数で扱います。この0または1の2進数一桁をビットと呼びます。4ビット(ニブル)で16パターンの情報を格納できます。ニブルは、16進数1桁で表現されます(0から9の数値にA,B,C,D,E,Fを加えたもの)。
ニブルが二つの8ビットは1バイトと呼ばれます。アルファベットなどの半角文字は1バイトで一つの文字を表現しますが、パック10進数では半分の4ビット(ニブル)に10進数の数字を割り当てます。1バイトに2桁の10進数を詰め込みます。この詰め込みの特性から「パックされた10進数」(パック10進数)と呼ばれます。
符号は最後のニブルで設定します。正(+)は16進数でC、負(-)はDが使われます。
| 値 | ASCII 16進値 | パック10進数16進値 |
|---|---|---|
| 12345 | 31 32 33 34 35 | 12 34 5C |
| -678 | 2D 36 37 38 | 67 8D |
| +90 | 2B 39 30 | 09 0C |
ゾーン10進数との対比
パック10進数と対照的な形式にゾーン10進数(Zoned Decimal)があります。ゾーン10進数は1バイトに1桁を格納します。ゾーン10進数は1バイトの前半4ビットをゾーンビット、後半4ビットを数値ビットとします。ゾーンビットがゾーン10進数の名前の由来です。
例えば数値「12345」はゾーン10進数の16数値では0xF1 0xF2 0xF3 0xF4 0xC5になります。上位4ビット(ゾーン部)は0xFが通常入り、最終桁のゾーンだけ符号となります。ビット列で表現すると以下になります。
| 0xF1 | 0xF2 | 0xF3 | 0xF4 | 0xC5 |
|---|---|---|---|---|
| 1111 0001 | 1111 0010 | 1111 0011 | 1111 0100 | 1100 0101 |
これに対してパック10進数の16進値は0x12 0x34 0x5Cです。ビット列で表現すると以下になります。
| 0x12 | 0x34 | 0x5C |
|---|---|---|
| 0001 0010 | 0011 0100 | 0101 1100 |
パック10進数はゾーン10進数と比べてメモリ容量が少ない(約半分で済む)点がメリットです。これは、ストレージコストやデータ転送速度が重要となるシステムにおいてアドバンテージとなります。
ゾーン10進数はアンパック10進数とも呼ばれています。パックされていない10進数という意味です。「アンパック10進数」の名称からは、ゾーン10進数がパック10進数の派生形のように聞こえます。しかし、歴史的にはゾーン10進数が先に存在し、より効率的なデータ格納法としてパック10進数が生まれました。
それにも関わらず、アンパック10進数という呼び方が広まった背景には、それだけパック10進数が定着していることを意味します。限られたメモリ資源の中で、いかに多くのデータを効率的に扱うかという課題に対し、エンジニアたちが生み出した工夫の一つがパック10進数です。
DTRIIによる変換
最初の10バイトが名前、次の5バイトが点数というフォーマットの固定長ファイルがあります。
Hayashida 12345
Riki -678
Ftadnyan +90
DTRIIには16進ダンプのビューア「Xダンプ」が同梱されており、任意のファイルの16進値を確認することができます。XダンプはWindowsスタートメニューのDTRIIのフォルダから選択します。
ファイルscore.txtの16進値を確認してみます。

Xダンプの特徴はGUIで16進値を確認できるだけでなく、ファイルに16進ダンプを出力できることです。出力結果は以下になります。
Adr 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
---------- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
0000000000 48 61 79 61 73 68 69 64 61 20 31 32 33 34 35 0D : Hayashida 12345.
0000000010 0A 52 69 6B 69 20 20 20 20 20 20 20 2D 36 37 38 : .Riki -678
0000000020 0D 0A 46 74 61 64 6E 79 61 6E 20 20 20 20 2B 39 : ..Ftadnyan +9
0000000030 30 0D 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 : 0...............
各行の5バイトの点数部分は、それぞれ以下のように表現されていると確認できました。
| 値 | ASCII 16進値 |
|---|---|
| 12345 | 31 32 33 34 35 |
| -678 | 20 2D 36 37 38 |
| +90 | 20 20 2B 39 30 |
それではDTRIIを利用して、ファイルscore.txtの点数をパック10進数に変換します。
以下のコマンドで実行します。文字型(c)からパック形式(p)に変換しています。
C:\dtr\dtrnt '{ c10 p5,c5 }' -PQ 3 C:\a\score.txt -A -S C:\a\pack.txt
正常に実行された場合は、コマンドを実行したカレントディレクトリにdtrmsgというファイルが生成され、以下の出力がなされます。
BIPROGY データ変換プログラム
データ変換終了(5R20T)
入力ファイル名--C:\a\score.txt
入力レコード数: 3
出力ファイル名--C:\a\pack.txt
出力レコード数: 3
出力ファイルpack.txtの16進値を確認します。
Adr 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
---------- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
0000000000 48 61 79 61 73 68 69 64 61 20 00 00 12 34 5C 0D : Hayashida ...4\.
0000000010 0A 52 69 6B 69 20 20 20 20 20 20 00 00 00 67 8D : .Riki ...g.
0000000020 0D 0A 46 74 61 64 6E 79 61 6E 20 20 00 00 00 09 : ..Ftadnyan ....
0000000030 0C 0D 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
以下の通り、パック10進数に変換されていることを確認しました。
| 値 | パック10進数16進値 |
|---|---|
| 12345 | 00 00 12 34 5C |
| -678 | 00 00 00 67 8D |
| +90 | 00 00 00 09 0C |
「12345」という5桁の数値も「12 34 5C」と3バイトで表現できます。当初は5バイトで表現されていた数値が、3バイトで表現されたことから、パック10進数は省データの方式であることが分かります。
まとめ
DTRIIを用いて固定長ファイル内の数値データをパック10進数へ変換し、変換結果を16進ダンプで確認する手順と結果を示しました。出力ファイルの16進値から、サンプルの点数フィールドが正しくパック10進数へ変換されていることを検証しています。DTRIIはパック10進数に変換するだけでなく、パック10進数から他のフォーマットに変換することもできます。DTRIIはデータを迅速かつ正確に変換し、活用可能な形に整えることに役立ちます。
We Are Hiring!
-
DTRは、BIPROGYが提供する高機能データ変換ツールです。DTRを使用することで、文字コードやファイル形式、レイアウトの違いに悩まされること無く、簡単にデータ変換することができます。また、データ変換の結果を使用して、高度なシステム連携を実施することができます。DTRIIはWindows版の商品名です。詳細は、以下をご覧ください。
https://www.biprogy.com/solution/service/dtr.html ↩



