バックグラウンド
3つのdoubleの検証を検討low
しwidth
、high
次の3つのルールが当てはまるようにします。
low < high
;width > 0
; とwidth
(high - low)
整数回「正確に」収まります。
基本的に、3つの値は、特定の数のビンに分割される範囲を指定する必要があります。各ビンは「正確に」等しい幅であり、範囲の一部が考慮されていません。
例えば:
(A) low = -0.5
、width = 0.005
およびhigh = 0.5
「正確に」200個の完全なビンを作成できるのに対し、有効なビン幅の範囲を指定します。
(B) low = -0.5
、width = 0.275
およびhigh = 0.5
3つの完全なビンを作成できたが、範囲の一部がそれらのビンでカバーされていないため、無効なビン幅の範囲を指定します。
問題
doubleの浮動小数点の性質を考えると、3番目の検証ルールにアプローチする最良の方法は何ですか?
私の最初の素朴な試みは次のとおりでした。
fmod( high - low, width ) == 0.0
しかし、残念ながら、fmodはたとえば(A)のように0.005を返します-私のデバッガーは、0.005のdoubleが実際にはの値を保持していることを教えてくれます0.0050000000000000001
。
許容誤差を含めるために独自のソリューションを自作する必要がありますか、それともこの問題に対するより洗練されたソリューションがありますか?
これは私が現在持っているものです:
bool valid(double range, double width, double tolerance = 0.000000001)
{
assert(width > 0 && range > 0);
while( range > 0 && range > tolerance )
{
range -= width;
}
return abs(range) <= tolerance;
}
許容範囲のデフォルト値の完全で完全な恣意性に注意してください...