【入門編】FLOAT BINARYとFLOAT DECIMALの精度と丸め誤差 – PL/Iの基本構文とデータ制御実践ガイド

PL/Iの「浮動小数点」と仲良くなる:丸め誤差の正体を見極めよう

こんにちは。メインフレームの世界へようこそ。
JavaやCOBOLでバリバリ開発してきたあなたにとって、PL/Iの宣言スタイルは少しばかり「古風で自由奔放」に見えるかもしれませんね。

今日は、PL/Iの中でも特に「数値計算の正確さ」を左右する、FLOAT BINARYFLOAT DECIMALという二つの浮動小数点型についてお話しします。これら、一見似ているようで、内部の振る舞いは全くの別物。ここを理解しておかないと、バッチ処理で「なぜか1円合わない」「比較演算で予期せぬ結果が出る」という、現場で最も胃が痛くなるトラブルに直面することになります。

でも安心してください。一つずつ紐解けば、決して怖い相手ではありません。

1. なぜ「2種類」もあるの?:バイナリとデシマルの違い

PL/Iには、浮動小数点数を表現するために `FLOAT BINARY` と `FLOAT DECIMAL` という二つの型が存在します。

  • FLOAT BINARY: コンピュータが計算しやすい「2進数」で内部データを保持します。計算速度は爆速ですが、私たちが普段使う「10進数」を正確に表せないことがあります(0.1が無限小数になるアレです)。
  • FLOAT DECIMAL: 人間にとって直感的な「10進数」の形式を保持します。金融系システムなど、10進数としての正確性が求められる場合に重宝します。

コードで見てみましょう

/i
/ 変数宣言の例 /
DCL VAL_BIN FLOAT BINARY(21); / 2進数で精度を指定 /
DCL VAL_DEC FLOAT DECIMAL(7); / 10進数で精度を指定 /

VAL_BIN = 0.1; / 2進数に変換される際、極めて微小な誤差が生じる /
VAL_DEC = 0.1; / 10進数ベースなので比較的正確 /

【現場の教訓】
「とりあえずFLOATでいいや」と安易に決めないでください。科学計算のように速度を最優先するなら `BINARY`、金額や数量のように「人間が計算結果をそのまま読めること」が重要な場合は `DECIMAL` を選ぶのが鉄則です。

2. 比較演算の「罠」:等価演算子(==)は信じてはいけない

浮動小数点数で最も注意すべきなのは、`IF A = B THEN` という比較です。

0.1を足し続けた結果と、最初から0.1を持っていた変数を比較すると、内部表現のわずかなズレ(丸め誤差)によって、期待に反して `FALSE` が返されることがよくあります。

やってはいけない比較の例

/i
DCL A FLOAT BINARY(21) INIT(0.0);
DCL I FIXED BINARY(31);

/ 0.1を10回足す /
DO I = 1 TO 10;
A = A + 0.1;
END;

/ ここでAは正確に1.0になっているか? /
IF A = 1.0 THEN / ← ここがFALSEになる可能性がある! /
PUT SKIP LIST(‘一致しました’);
ELSE
PUT SKIP LIST(‘残念、一致しませんでした’);

このように、浮動小数点数の比較においては、「許容誤差(イプシロン)」という考え方を取り入れるのが、ベテランの作法です。

3. ベテランアーキテクトからのアドバイス:どう乗りこなすか

メインフレームの現場で長く愛されてきたPL/Iには、こうした数値計算の機微を制御するためのオプションが豊富に用意されています。

1. 比較は「差分」で判定する:
`IF ABS(A – 1.0) < 0.000001 THEN ...` のように、二つの値の差が十分に小さければ「等しい」とみなすロジックを組みましょう。 2. 精度を明示する:
`FLOAT BINARY(21)` の `21` は、保持するビット数です。必要以上に精度を高くすると計算負荷が上がりますし、低すぎれば誤差が増大します。仕様に合わせて適切な精度を設定してください。
3. 固定小数点(FIXED)との使い分け:
もし、あなたが扱っているのが「お金」なら、`FLOAT` を使うこと自体がミスかもしれません。その場合は、`FIXED DECIMAL(15, 2)` のような、小数点位置を固定した型を使うのが、COBOL使いのあなたにも馴染み深い、最も安全な道です。

最後に:怖がらずに、実験を繰り返そう

PL/Iは、非常に強力な言語です。コンパイラが裏でどのような計算を行っているかを想像し、それを制御できるようになったとき、あなたは一人前の「メインフレーム・アーキテクト」へ一歩近づいたと言えるでしょう。

「まずは動かしてみる」。メインフレームの環境は重厚ですが、その分、答えは常にコンパイラの中にあります。小さなテストプログラムを書いて、どのような精度で値が格納されるか、ぜひ追いかけてみてください。

もし、計算のズレで夜眠れないような夜があれば……その時は、いつでも私を頼ってくださいね。一緒にデバッグしましょう。

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