【実務・中級編】FLOAT BINARY/DECIMALの浮動小数点演算 – PL/Iの基本構文とデータ制御実践ガイド

メインフレームの「浮動小数点」と心中しないために――PL/IにおけるFLOAT精度の深淵

現場の皆さん、お疲れ様。今日もバッチのログと睨めっこしているのか?
最近、レガシーシステムのクラウド移行やオープン系連携の案件が増えているが、そこで最も「足元をすくわれる」のが浮動小数点演算だ。PL/IはCOBOLよりも遥かに高度な数学的表現が可能だが、その分、仕様を理解していないと、ある日突然「1円の差異」や「謎の異常終了」という形で牙を剥く。

今日は、IEEE 754とIBM形式の浮動小数点の違い、そして現場で必ずぶつかる「丸め誤差」の正体について、腹を割って話そうと思う。

1. なぜ「FLOAT」を使うのかを再定義する

まず大前提だ。基幹システムの金勘定でFLOATを使うのは、原則として禁じ手だ。金銭計算には必ず `FIXED DECIMAL` を使う。では、FLOATはどこで使うのか? それは複雑な統計処理、科学計算、あるいは外部システム(C言語やJavaなど)とのデータ交換の際だ。

PL/Iには大きく分けて二つの浮動小数点型がある。

  • FLOAT BINARY: 2進浮動小数点。ハードウェアのレジスタに直結しており、計算速度が極めて速い。
  • FLOAT DECIMAL: 10進浮動小数点。人間が直感的に扱えるが、内部的には変換が入るため、パフォーマンスと精度のトレードオフを意識する必要がある。

浮動小数点の「罠」

メインフレームの歴史を語る上で避けて通れないのが、IBM形式(16進浮動小数点)とIEEE 754形式の混在だ。近年のz/ArchitectureではIEEE 754が標準だが、古いプログラムはIBM形式で計算している。この変換の際に発生する「わずかなビットの欠落」が、後の比較演算(`IF A = B THEN`)を破壊する。

2. 実践:丸め誤差を制御するコーディング標準

百聞は一見にしかず。以下のコードを見てくれ。浮動小数点を扱う際に最低限守るべき、堅牢な記述のサンプルだ。

1
/ 浮動小数点演算における精度制御のデモンストレーション /
FLOAT_TEST: PROCEDURE OPTIONS(MAIN);

/ 宣言:精度を明示する。FLOAT BIN(53)は倍精度(64bit)に相当 /
DCL VALUE_A FLOAT BIN(53) INIT(0.1);
DCL VALUE_B FLOAT BIN(53) INIT(0.2);
DCL RESULT FLOAT BIN(53);

/ 比較用のしきい値(EPSILON)を定義する /
DCL EPSILON FLOAT BIN(53) INIT(1E-10);

/ 計算処理 /
RESULT = VALUE_A + VALUE_B;

/ 危険な比較:浮動小数点の直接比較は「死」を意味する /
/ IF RESULT = 0.3 THEN … (これは成立しないことが多い) /

/ 安全な比較:差分が許容範囲内かをチェックする /
IF ABS(RESULT – 0.3) < EPSILON THEN PUT SKIP LIST('計算結果は許容誤差内で一致しました'); ELSE PUT SKIP LIST('致命的な精度欠落が発生しました'); / 外部データ出力時の丸め:ROUNDビルトインを必ず活用せよ / / 整数部のみを取り出すような強引なキャストはバグの温床 / DCL FINAL_VAL FIXED DEC(15, 2); FINAL_VAL = ROUND(RESULT, 2); END FLOAT_TEST; ---

3. ONユニットと例外ハンドリングの作法

浮動小数点演算で最も怖いのは「オーバーフロー」や「無効な演算(0除算など)」だ。これらを放置して異常終了させるのは、アーキテクトとして恥と知れ。

必ず `ON CONVERSION` や `ON FIXEDOVERFLOW` (浮動小数点の場合は `ON OVERFLOW`) を適切に配置すること。

1
/ 浮動小数点例外のトラップ /
ON OVERFLOW BEGIN;
PUT SKIP LIST(‘警告: 浮動小数点のオーバーフローが発生しました’);
/ ここでログ出力やエラーフラグの制御を行い、安全に終了させる /
STOP;
END;

重要なのは、「異常終了させてジョブを止める」ことと「エラーをキャッチして正常終了コードを返して後続を止める」ことの使い分けだ。基幹バッチであれば、後者を選択すべきケースが多い。

4. 現場のアーキテクトから後輩へのアドバイス

1. 「とりあえずFLOAT」を禁止せよ:
`FIXED BIN` や `FIXED DEC` で表現できるものは、絶対にそちらを使え。浮動小数点を使う場合は、必ず設計書に「なぜこの精度が必要か」を明記させること。
2. バイナリ・エディタで確認する癖を:
VSAMやフラットファイルにFLOATを書き出した後、ダンプリストを見てくれ。自分が意図したビット列になっているか? 16進数で `41100000…` といった値がどう見えるか理解できて初めて、プロと言える。
3. ONユニットは局所化せよ:
プログラム全体に広域的なONユニットを置くのではなく、計算を行っているPROCEDUREブロック内に限定して配置することで、デバッグ時のスタックトレースが劇的に読みやすくなる。

浮動小数点は、コンピュータが人間という「曖昧な生き物」と「厳密な数学」の間で妥協した結果の産物だ。その妥協のルールを理解せずして、大規模なシステムを支えることはできない。

もし、計算結果が「0.30000000000000004」になって泣きそうになっている後輩がいたら、この記事をそっと渡してやってくれ。それが一番の近道だ。

さて、そろそろ次のマイグレーションの設計に戻るとしよう。質問があればいつでも聞いてくれ。現場からは以上だ。

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