0

バックグラウンド

3つのdoubleの検証を検討lowwidthhigh次の3つのルールが当てはまるようにします。

  1. low < high;
  2. width > 0; と
  3. width(high - low)整数回「正確に」収まります。

基本的に、3つの値は、特定の数のビンに分割される範囲を指定する必要があります。各ビンは「正確に」等しい幅であり、範囲の一部が考慮されていません。

例えば:

(A) low = -0.5width = 0.005およびhigh = 0.5

「正確に」200個の完全なビンを作成できるのに対し、有効なビン幅の範囲を指定します。

(B) low = -0.5width = 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;
}

許容範囲のデフォルト値の完全で完全な恣意性に注意してください...

4

1 に答える 1

1

二重比較の許容誤差を使用するアプローチは妥当なものです。今必要なのは、残りの要件分析を実行して、実際にどれだけ正確である必要があるかを判断することだけです:)

最大精度がわかっている場合は、比較のために整数値まで乗算します。

于 2012-06-19T11:31:54.897 に答える