PL/Iの「数」の扱いに悩むあなたへ:FIXED BINARYとFIXED DECIMALの混在演算を攻略する
メインフレームの世界へようこそ。JavaやCOBOLでバリバリ開発してきた皆さんにとって、PL/Iのコードを初めて見た時の「なんだか古めかしいな」という第一印象は、ある意味で正解です。しかし、PL/Iは非常に強力で、数学的に誠実な言語でもあります。
今回は、現場のマイグレーション案件で「なぜか計算結果が合わない」「精度落ちが発生する」というトラブルの筆頭格、「FIXED BINARYとFIXED DECIMALの混在演算」について、その裏側のルールを紐解いていきましょう。
—
1. そもそも、なぜ型が分かれているのか?
PL/Iの数値型は、大きく分けて2種類あります。
- FIXED BINARY(固定小数点2進数): コンピュータが本来得意な「2進数」で計算します。速度は爆速ですが、10進数の「0.1」を厳密に表現できません。
- FIXED DECIMAL(固定小数点10進数): 人間が直感的に使う「10進数」をそのまま扱います。COBOLの`COMP-3`に近い感覚で、金額計算など「誤差が許されない」処理で重宝されます。
この2つを混ぜて計算させると、PL/Iコンパイラは「どちらの世界のルールで計算するか」を必死に判断します。ここでルールを知らないと、思わぬ落とし穴にハマるのです。
—
2. コンパイラは「どっちの味方」をするのか?
結論から言うと、異なる型同士が演算されるとき、PL/Iは基本的に「FIXED DECIMAL」を優先して、FIXED BINARYをFIXED DECIMALに変換してから計算しようとします。
なぜなら、精度の欠落が許されない10進数(金額など)を、2進数に引きずられて破壊してはいけないからです。しかし、この「型昇格(プロモーション)」には、コンパイラが自動的に決定する「中間結果の精度」という見えない壁が存在します。
実践コードで見てみましょう
/ 混在演算のテストプログラム /
TEST_PROG: PROC OPTIONS(MAIN);
DCL B_VAL FIXED BIN(31) INIT(100); / 2進数の100 /
DCL D_VAL FIXED DEC(5, 2) INIT(12.34); / 10進数の12.34 /
DCL RESULT FIXED DEC(9, 2); / 計算結果格納用 /
/
【ここがポイント!】
B_VAL(FIXED BIN) が内部的に FIXED DEC に変換されてから
D_VAL との加算が行われます。
/
RESULT = B_VAL + D_VAL;
PUT SKIP LIST(‘計算結果は:’, RESULT);
END TEST_PROG;
—
3. なぜ「精度保持」で悩むのか?
現場でよくある失敗は、「中間結果の桁あふれ(OVERFLOW)」です。
コンパイラは自動昇格の際、計算結果が収まりきるように、ある程度の桁数を確保してくれます。しかし、複雑な計算式(例えば、`A B / C + D` のような式)になると、途中で桁数が増えすぎてしまい、メモリ上の制約から「デフォルトの精度」で切り捨てが発生することがあります。
私からのアドバイス:明示的にキャストする
コンパイラ任せにせず、自分で型を合わせるのが、バグを生まない「プロの作法」です。PL/Iには、型を変換するための組み込み関数(`DECIMAL`や`BINARY`)があります。
/ 安全策:明示的にDECIMAL型に変換してから計算する /
RESULT = DECIMAL(B_VAL, 9, 0) + D_VAL;
こうすることで、「計算結果の桁数は9桁、小数部は0」であることを明示できます。これにより、コンパイラが裏で勝手に変な推論をして精度を落とすリスクをゼロにできるのです。
—
4. 怖がらなくて大丈夫です
PL/Iは一見すると複雑な仕様の塊に見えますが、それは「数値の精度を極限まで制御したい」というエンジニアの執念の現れでもあります。
- 「計算結果が怪しいな?」と思ったら: まずはコンパイラがどの型に昇格させているかをマニュアル(IBM Knowledge Center等)で確認しましょう。
- 「迷ったら明示的に変換」: 組み込み関数を使って、計算の途中で型を揃える。これが最もトラブルを回避できる近道です。
PL/Iは、あなたが書いたコードの意図を忠実に実行しようとします。型をコントロール下に置くことさえできれば、これほど頼りになる相棒はいません。
もし現場で「PL/Iのコンパイルでエラーが出た!」「計算が合わない!」と悩んだら、またいつでも相談してくださいね。一つずつ紐解いていけば、必ず解決策は見つかります。
さあ、今日もメインフレームと一緒に、安定したシステムを作り上げましょう!
