【入門編】FIXED DECIMALとPACKED DECIMALの内部形式 – PL/Iの基本構文とデータ制御実践ガイド

メインフレームの世界へようこそ!PL/Iの「FIXED DECIMAL」と「PACKED DECIMAL」を優しく紐解こう

こんにちは。メインフレームの深淵で、長年PL/Iという「言語の宝石」と向き合ってきたシステムアーキテクトです。

JavaやCOBOLの経験がある皆さんにとって、PL/I(ピーエル・ワン)は少し不思議な書き物に見えるかもしれませんね。でも、安心してください。「なぜそんな動きをするのか?」という理屈さえ分かれば、これほど頼もしく、かつ強力な言語はありません。

今日は、基幹システムの心臓部である「10進演算」の要、`FIXED DECIMAL`と`PACKED DECIMAL`について、現場の知見を交えて解説していきます。

1. なぜ「パック10進数」が必要なのか?

皆さんが普段使っているJavaの`double`型や、C言語の`float`型は「浮動小数点」と呼ばれますよね。これらは科学技術計算には速いのですが、金融系システムには致命的な弱点があります。それは「0.1 + 0.2 が 0.30000000000000004 になる」ような、微小な誤差です。

お金を扱うシステムで1円でも合わなかったら大変ですよね?そこで登場するのが「パック10進数」です。これは10進数をそのままの形でメモリに詰め込む方式で、誤差が絶対に発生しません。

パック10進数のイメージ

メモリ上では、1バイトの中に2つの数字を詰め込みます。

  • 数値:`1234`
  • パック形式:`[12][34][3C]` (最後の`C`はプラスの符号です)

このように、1バイトを無駄なく使い切ることで、メモリ効率と正確性を両立させているんです。

2. PL/Iでの宣言:FIXED DECIMALの魔法

PL/Iでは、このパック10進数を`FIXED DECIMAL`という属性を使って宣言します。

1
/ 5桁の整数、かつ小数点以下2桁を持つフィールドの宣言 /
DCL BALANCE FIXED DECIMAL(7, 2);

この`(7, 2)`という書き方は、COBOLの`PIC S9(5)V99`に相当します。

  • `7`:全体の有効桁数(精度)
  • `2`:小数点以下の桁数

この指定を間違えると、システム側が「あ、桁あふれしそうだ」と判断して、計算の途中で勝手に精度を変換してしまうことがあります(いわゆる「中間計算の精度喪失」です)。これには十分注意が必要です。

3. 実践コード:誤差を防ぐ「おまじない」

現場でよくあるトラブルは、「計算過程で小数点が消えてしまった!」というものです。PL/Iは賢すぎて、計算するたびに「最適な精度」へ自動変換しようとするため、時にはお節介に感じることもあります。

以下のコードは、現場で私がよく使う「精度を維持するための記述」です。

1
TEST_CALC: PROCEDURE OPTIONS(MAIN);

/ 精度を指定して変数を宣言します /
DCL PRICE FIXED DECIMAL(9, 2) INIT(100.50);
DCL QUANTITY FIXED DECIMAL(5, 0) INIT(3);
DCL TOTAL FIXED DECIMAL(13, 2); / 結果を格納する十分な精度を確保 /

/

  • 計算式:
  • PL/Iは計算結果の精度を自動で保持しようとしますが、
  • 念のため、結果を受け取る側の精度が十分であることを確認します。

/
TOTAL = PRICE QUANTITY;

/ 結果の表示(PUT LISTはCOBOLのDISPLAYに近い感覚です) /
PUT SKIP LIST(‘計算結果:’, TOTAL);

END TEST_CALC;

4. 現場のアーキテクトから、3つのアドバイス

PL/Iを扱う上で、これだけは覚えておいてください。

1. 「精度」は常に余裕を持つこと
計算結果が入りきらないと、`FIXEDOVERFLOW`(固定小数点オーバーフロー)という例外が発生します。これはプログラムが強制終了する原因の筆頭です。結果の格納先は、常に計算過程よりも大きな桁数で定義する癖をつけましょう。

2. 変数の属性を揃える
`FIXED DECIMAL`と`FIXED BINARY`(2進数)を混ぜて計算すると、コンパイラが内部で型変換を行います。これがパフォーマンス劣化や意図せぬ精度の丸めを招くことがあります。可能な限り「同じ属性同士」で計算することを心がけてください。

3. 「見えない符号」を意識する
パック10進数の末尾には必ず「符号」が入ります。データ移行などで他システムからバイナリデータを受け取る際、この符号が化けていると計算が狂います。ダンプリストを見たときに「最後が`C`や`D`になっていないな?」と思ったら、それは要注意のサインです。

最後に:怖がらなくて大丈夫

最初は`DCL`という宣言文や、`FIXED DECIMAL`の桁数指定に戸惑うかもしれません。でも、メインフレームの言語は、一度ルールを覚えると非常に安定して動いてくれる「職人気質な相棒」のような存在です。

もし分からないことがあれば、いつでも聞いてくださいね。皆さんのレガシー移行プロジェクトが、無事に成功することを心から応援しています!

タイトルとURLをコピーしました