0

重複の可能性:
10 進数を 2 進数で正確に表現できないのはなぜですか?

言語 c++ 配列を宣言していて、その中に数値 (double 型) を保存しています。次に、配列内の 2 つの要素それぞれの違いを比較し始めます。例えば

a[1] = 0.05
a[2] = 0.1
a[3] = 0.15

だから私は次のことをするとき

if(a[3] - a[2] == a[2] - a[1] )

条件が偽になる!!

デバッグ後、0.05 が 0.0499......993 として配列に保存されていることがわかりました。ケースは 0.10 と 0.15 で似ています。

どうすればこの問題を克服できますか?

4

4 に答える 4

8

浮動小数点数を比較して完全に等しいことは絶対にしないでください。

理由を理解するには、すべてのコンピューター科学者が浮動小数点演算について知っておくべきことを読む必要があります。

于 2011-05-09T14:52:02.910 に答える
3

正確な計算をしたい場合は、有理数の使用を検討することをお勧めします。C++ で有理数のクラスを実装することは可能です。Boost.Rationalはこの例です。

浮動小数点を使用したい場合は、おそらく次のように、等しいかどうかではなく、「近いかどうか」を比較する必要があります。

const float EPSILON = 0.0001; //< Some acceptable limit for equivalence
float d1 = a[3] - a[2];
float d2 = a[2] - a[1];

if (fabs(d1 - d2) < EPSILON) {
    // Consider d1 and d2 eqivalent
}
于 2011-05-09T14:54:18.990 に答える
2

浮動小数点数学は、コンピューターが通常期待するような結果をもたらさない領域の1つです。これを参照してください。

あなたにできることは、次のようなことを考えて delta = 0.00001
fabs((a[3]-a[2]) - (a[2]-a[1])) < delta

注:これが通貨または通貨データと関係がある場合は、整数/長整数などを使用してください。float/ doubleを使用してお金を表すことは、上記の理由および上記のリンクでさらに説明されている理由から、悪い悪いことです。

于 2011-05-09T14:52:48.730 に答える
0

いくつかのオプションがあります:

(1) これらの数値を正確に格納する型を使用します。これらの数値については、おそらく int を使用して元の数値の 100 倍として格納するのが最も簡単です。

(2) double を等しいかどうか比較することは悪い戦略であると理解してください。数値を double として格納する場合、固定ビット数で 2 進数で正確に表現できない数値があります。0.05 (および 0.5 5 50 など) は、それらの数値の 1 つです。

于 2011-05-09T14:56:26.347 に答える