浮動小数点の数値を比較する
一般的に浮動小数点は精度の問題から完全一致による比較が難しい。
一例として、1.0
と、0.1
を10回加算した数値は一致しない。
v0 = 1.0 v1 = 0 ; 10.times{ v1 += 0.1 } p v0 == v1 #=> false
浮動小数点の比較を行うには、一致とみなす許容値を決めて、数値が許容値の範囲内であれば一致とみなすアプローチが必要だ。
簡単なのは、浮動小数点を文字列化してしまい、指定した桁数まで一致するかを確認する方法だ。
浮動小数点の数値の文字列化には、sprintf
が使用できる。
v0 = 1.0 v1 = 0 ; 10.times{ v1 += 0.1 } format = "%.3e" # 小数点以下3桁で比較する p sprintf(format, v0) == sprintf(format, v1) #=> true
より細かな比較を行いたいなら、Float::EPSILON
という定数を基準にして、比較を行うと良い。
この定数は1.0 + Float::EPSILON != 1.0
となる最小の値を示すものだ。
v0 = 1.0 v1 = 0 ; 10.times{ v1 += 0.1 } p (v0 - v1).abs / v0.abs <= Float::EPSILON && (v1 - v0).abs / v1.abs <= Float::EPSILON