1. 導入:なぜ精度の定義が重要なのか
メインフレームの基幹システムにおいて、計算結果の「端数処理」や「桁落ち」は許されないバグとなります。PL/I(Programming Language I)は、ハードウェアの性能を最大限に引き出しつつ、商用計算で求められる10進数の正確性を維持するために設計されました。単なる文法変換ではなく、数値精度を正しく理解しガバナンスを効かせることが、システム移行や保守における品質安定の鍵となります。
2. 基礎知識:精度(p)と位取り(q)
PL/Iの算術データにおいて、精度は「(p, q)」という形式で定義されます。
p (Precision):有効桁数の合計(全体で何桁か)
q (Scale):小数点の位置(そのうち小数点以下が何桁か)
例えば「FIXED DECIMAL(5, 2)」であれば、全体で5桁、うち小数点以下が2桁を意味し、「999.99」までを扱えます。この定義が加減乗除の際、どのように変化(伝播)するかを理解することが、計算誤差を防ぐ第一歩です。
3. 実装/解決策:精度伝播の適切な設計
算術演算を行う際、コンパイラはデフォルトのルールに従って中間結果の精度を決定しますが、意図しない桁溢れや切り捨てが発生することがあります。これを防ぐには、計算式の中間段階で意図的に「DECIMAL関数」などを用いて精度を明示的に制御することが重要です。
4. サンプルプログラム:精度の明示的制御
以下の例は、計算途中で精度が不足しないよう、一時変数を用いて計算結果を保持する定石パターンです。
/ PL/I サンプルコード:精度の制御 /
PROCEDURE OPTIONS(MAIN);
/ 精度(5,2)の変数を定義 /
DCL A FIXED DECIMAL(5, 2) INIT(123.45);
DCL B FIXED DECIMAL(5, 2) INIT(67.89);
/ 計算結果を受け取る変数を大きめに確保する /
/ 計算結果は (p, q) = (11, 4) となるように調整 /
DCL RESULT FIXED DECIMAL(11, 4);
/ 中間結果の精度を維持した計算 /
RESULT = A B;
PUT SKIP LIST(‘計算結果は: ‘ || TRIM(RESULT));
/
- コメント:
- 乗算の場合、精度は p = p1 + p2, q = q1 + q2 となるのが基本です。
- 桁溢れを防ぐため、受け取り側の変数は十分なサイズを確保してください。
/
END;
5. 応用・注意点:現場で役立つガバナンス
現場での移行や改修において、最も陥りやすい罠は「既存の数値定義をそのまま流用し、計算式だけ複雑化させる」ことです。
注意点1:定数との演算時、定数側にも精度が割り当てられます。意図しない精度にならないよう、定数も「10.00」のように小数点以下を明示してください。
注意点2:除算(DIVIDE関数)は特に注意が必要です。商の精度を適切に指定しないと、デフォルト設定により小数点以下が切り捨てられることがあります。
結論:複雑な計算を行う際は、計算過程を分解し、それぞれのステップで精度を意識的に再定義(ガバナンス)することが、堅牢なシステム構築の鉄則です。

コメント