1. 導入:なぜ計算順序が重要なのか
COBOLでの数値計算、特に金額や歩留まりの計算で「計算結果が微妙に合わない」という経験はありませんか?実は、コンピュータの有限な桁数による処理では、演算の順序一つで結果に誤差が生じることがあります。特に除算(割り算)は、割り切れない場合に端数が発生するため、記述の順序を間違えると累積誤差によって計算が狂ってしまうのです。今回は、現場でトラブルを防ぐための「精度を維持するデータ操作の作法」を解説します。
2. 基礎知識:演算の仕組みと誤差
COBOLの数値データ項目(PIC句)は、定義された桁数までしか保持できません。例えば、計算途中の値として「1÷3」を実行すると、システム内部では「0.333333…」が生成されます。ここで、先に除算を行ってから掛け算をすると、この「切り捨てられた端数」がそのまま計算に持ち越されます。このわずかな誤差が、大きな金額計算や集計処理において致命的なズレを引き起こすのです。
3. 実装/解決策:計算順序の最適化
誤差を最小限にするための鉄則は、「可能な限り除算を最後に行う」ことです。数式を「(分子 × 乗数) ÷ 分母」の形に変形することで、除算によって発生する端数を計算の最終段階まで持ち込まずに済みます。また、中間結果を保持するワークエリアには、十分な桁数(特に小数点以下の桁数)を確保しておくことも重要です。
4. サンプルプログラム
以下のコードは、除算の順序による誤差の違いを比較する例です。実務で計算式を組む際の参考にしてください。
IDENTIFICATION DIVISION.
PROGRAM-ID. PRECISION-SAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
- 計算結果を比較するための定義
01 WS-RESULT-NG PIC 9(09)V99.
01 WS-RESULT-OK PIC 9(09)V99.
PROCEDURE DIVISION.
- 【悪い例】先に除算を行うため、途中で端数が切り捨てられ、結果が0.99…になる可能性がある
COMPUTE WS-RESULT-NG = 1 / 3 3.
- 【良い例】先に掛け算を行い、最後に除算することで精度を保つ
COMPUTE WS-RESULT-OK = 1 3 / 3.
DISPLAY “NG(除算先行): ” WS-RESULT-NG.
DISPLAY “OK(乗算先行): ” WS-RESULT-OK.
STOP RUN.
5. 応用・注意点:現場で陥りやすい罠
現場では以下の点にも注意してください。
・中間項目の桁数:計算結果を受け取る項目だけでなく、計算途中のCOMPUTE文で参照される一時的な数値項目が小さいと、そこでオーバーフローや桁落ちが発生します。COMPUTE文を使う際は、意識的に長めのワーク項目を定義しましょう。
・丸め誤差の制御:COBOLのROUNDED句を使用すると四捨五入ができますが、どこで丸めるかも非常に重要です。要件定義書で指定された「端数処理ルール(切り捨て、四捨五入、切り上げ)」を厳密に守るためにも、計算順序の最適化と組み合わせることを忘れないでください。
正確な計算こそがCOBOLエンジニアの誇りです。ぜひ明日のコーディングから意識してみてください。

コメント