皆さん、こんにちは。IBMメインフレームの世界へようこそ。
「PL/I? なんだか古めかしい名前だな…」と身構える必要はありません。PL/Iは、ビジネス計算の正確さと、科学技術計算の柔軟性を併せ持った、非常に知的で「大人な」言語です。
特に、銀行や保険会社の基幹システムで長年愛されてきたのが、今回解説する「FIXED DECIMAL」というデータ型です。Javaの`BigDecimal`やCOBOLの`COMP-3`と親戚のような関係ですが、PL/I流の「作法」を理解すると、この言語がなぜこれほどまでに信頼されているのかが見えてきますよ。
—
1. FIXED DECIMAL(p,q)の正体:パック10進数の世界
PL/Iで数値を扱う際、`FIXED DECIMAL(p, q)`と宣言することがよくあります。これは、メモリの中に数値をどう詰め込むかという「設計図」のようなものです。
- p (Precision): 全体の桁数
- q (Scale): 小数点以下の桁数
例えば `DCL AMOUNT FIXED DECIMAL(7, 2);` と書くと、「全体で7桁、そのうち小数点が2桁」という意味になります。つまり、整数部分は5桁(7 – 2 = 5)ですね。
なぜ「パック」なのか?
メインフレームのメモリは貴重です。1バイト(8ビット)の中に、数字を2つずつギュウギュウに詰め込むことで、ストレージを節約しています。これが「パック10進数」です。
- イメージ: 100円玉(数字)を1つの財布(1バイト)に2枚ずつ入れて、効率よく運んでいる様子を想像してください。
- 端数処理の強み: 浮動小数点(Float)のように「0.1 + 0.2 が 0.30000000004 になる」といった誤差が発生しません。ビジネスの現場で「1円のズレ」が許されない理由が、このパック10進数にあるのです。
—
2. 実際に書いてみよう:PL/Iプログラムの基本構造
PL/Iのプログラムは、`PACKAGE`や`PROCEDURE`という「入れ物」の中に記述します。まずは、一番シンプルなメインプログラムの例を見てみましょう。
1
/ プログラム名:CALC_SAMPLE /
/ OPTIONS(MAIN)は、ここがプログラムの入り口ですよ!という合図です /
CALC_SAMPLE: PROCEDURE OPTIONS(MAIN);
/ 7桁のうち小数2桁の変数を宣言 /
DCL TOTAL_PRICE FIXED DECIMAL(7, 2) INIT(0);
DCL UNIT_PRICE FIXED DECIMAL(5, 2) INIT(123.45);
DCL QUANTITY FIXED DECIMAL(3, 0) INIT(10);
/ 計算処理 /
/ PL/Iは自動的に小数点の位置を揃えて計算してくれます /
TOTAL_PRICE = UNIT_PRICE QUANTITY;
/ 結果を表示(PUT SKIPは改行して出力する命令) /
PUT SKIP LIST(‘合計金額は: ‘, TOTAL_PRICE);
END CALC_SAMPLE;
—
3. 「勝手にやってくれる」PL/Iの賢さと注意点
PL/IがJavaやCと大きく違うのは、「演算時の精度保持をコンパイラが自動で計算してくれる」点です。
例えば、`FIXED DECIMAL(5, 2)` と `FIXED DECIMAL(3, 0)` を掛け算すると、結果は自動的に「桁あふれ」しない十分な大きさの精度で計算されます。これを「中間精度」と呼びますが、あまりに複雑な計算を繰り返すと、たまにコンパイラが「これ以上は精度を保てないよ!」と警告を出してくることがあります。
ここが現場の落とし穴!
- 桁あふれ (Fixed Overflow): 宣言した桁数(p)を超えてしまうと、実行時にエラー(ONCODE)が発生してプログラムが異常終了します。
- 調整のコツ: 計算結果を代入する先の変数は、常に余裕を持った桁数で宣言する。これがベテランの知恵です。
—
読者の皆さんへ:怖がらなくて大丈夫です
PL/Iのコードを初めて見ると、大文字の羅列や独特の省略記法に圧倒されるかもしれません。でも、一つひとつバラしてみると、非常に論理的で、計算間違いを極限まで減らそうとする「エンジニアの優しさ」に満ちた言語だと気づくはずです。
もしバッチ処理の改修で行き詰まったら、まずはその変数が「何桁なのか」「小数点はどこか」を紙に書いてみてください。それだけで、PL/Iが裏でどんな計算をしているのか、不思議と見えてくるようになります。
これからも、メインフレームの深淵を一緒に紐解いていきましょう。何か具体的なエラーや、もっと知りたい仕様があれば、いつでも聞いてくださいね!
