【Fortran学習|初心者向け】レガシーな「算術IF文」が招く数値計算の罠と、安全な比較方法

導入:なぜ算術IF文での「ゼロ判定」は危険なのか

プログラミングの世界、特に科学技術計算の現場では「AとBは等しいか?」を判定する場面が頻繁にあります。かつてのFortranなどで多用された「算術IF文」は、簡潔に見える反面、浮動小数点数(実数)を取り扱う現代のコンピューティングにおいては、プログラムのバグや予期せぬ暴走を招く最大の原因の一つです。今回は、なぜ算術IF文でのゼロ判定が不安定なのか、そしてどう書き換えるべきかを解説します。

基礎知識:浮動小数点数の「誤差」を知る

コンピュータは実数を正確に表現するのが苦手です。例えば「0.1」という単純な数字でさえ、コンピュータ内部では2進数の無限小数となり、微小な丸め誤差が生じます。
算術IF文 `IF (A – B) 10, 20, 30` は、(A – B) の値が「負なら10へ」「ゼロなら20へ」「正なら30へ」分岐します。しかし、計算結果が数学的に0であっても、コンピュータ内部では `0.00000000000000001` のような微小な値になり、判定が「ゼロ」ではなく「正」に流れてしまうケースが多発します。これが「不確実性」の正体です。

実装・解決策:許容誤差(イプシロン)を導入する

実数同士の比較では、「完全に一致するかどうか」ではなく「差が十分に小さいかどうか」を判定するのが鉄則です。この「十分に小さい値」を EPS(イプシロン) と呼びます。
具体的には、`(A – B)` の絶対値をとったものが、設定した極小値 `EPS` より小さい場合に「等しい(ゼロである)」とみなす論理に書き換えます。

サンプルプログラム:安全な比較への書き換え例

以下は、算術IF文から現代的な比較手法へ移行するためのPythonによるサンプルコードです。

比較のための微小な許容誤差(イプシロン)を定義
EPS = 1e-9

def compare_values(a, b):
# 算術IF文の代わりに、絶対値とEPSを用いた判定を行う
diff = abs(a – b)

if diff < EPS: # 差が許容範囲内であればゼロとみなす print("判定: 2つの値は等しいとみなします") elif (a - b) > 0:
print(“判定: Aの方が大きいです”)
else:
print(“判定: Bの方が大きいです”)

実行テスト
val_a = 0.3
val_b = 0.1 + 0.1 + 0.1 # コンピュータ上では0.30000000000000004になる可能性がある
compare_values(val_a, val_b)

応用・注意点:現場で役立つアドバイス

1. EPSの選び方: 計算する数値の規模(スケール)に合わせてEPSを調整してください。非常に大きな数や小さな数を扱う場合は、相対誤差を考慮した判定(`abs(a – b) / max(abs(a), abs(b)) < EPS`)が必要になることもあります。 2. レガシーコードの扱い: 既存の古いソースコードを修正する際は、単にIF文を書き換えるだけでなく、その分岐が「なぜゼロ判定を必要としていたのか」というロジック全体を見直すことが重要です。
3. 避けるべき習慣: `if (a == b)` という直接比較も、浮動小数点数においては算術IF文と同様の理由で推奨されません。常に「近傍にあるか」を判定する癖をつけましょう。

現代の数値計算において、厳密なイコール判定は「幻想」です。常に誤差を考慮した設計を心がけることが、堅牢なシステム構築への第一歩となります。

コメント

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