7

ばかげている場合は申し訳ありませんが、答えを見つけることができませんでした。

#include <iostream>

using namespace std;

int main()
{
double a(0);
double b(0.001);
cout << a - 0.0 << endl;
for (;a<1.0;a+=b);
cout << a - 1.0 << endl;
for (;a<10.0;a+=b);
cout << a - 10.0 << endl;
cout << a - 10.0-b << endl;
return 0;
}

出力:
0
6.66134e-16
0.001
-1.03583e-13

MSVC9、MSVC10、Borland C ++ 2010でコンパイルしてみました。それらはすべて、最終的に約1e-13のエラーで到着します。1000、10000の増分だけで、このような重大なエラーが蓄積されるのは正常ですか?

4

4 に答える 4

13

はい、これは通常の数値表現の浮動小数点エラーです。これは、ハードウェアがほとんどの浮動小数点数を正確に格納するのではなく、概算する必要があるという事実に関係しています。したがって、使用するコンパイラは重要ではありません。

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと

于 2010-05-07T01:24:46.340 に答える
2

これが、浮動小数点エラーを使用するときに絶対にすべきではない理由です。

if( foo == 0.0 ){
    //code here
}

代わりに

bool checkFloat(float _input, float _compare, float _epsilon){
    return ( _input + _epsilon > _compare ) && ( _input - _epsilon < _compare );
}
于 2010-05-07T01:40:29.080 に答える
2

これについて考えます。すべての操作でわずかなエラーが発生しますが、次の操作ではわずかに誤った結果が使用されます。十分な反復を行うと、真の結果から逸脱します。必要に応じて、式をフォームに書き、t0 = (t + y + e), t1 = (t0 + y +e)イプシロンで項を計算します。それらの項から、おおよその誤差を推定できます。

エラーの 2 番目の原因もあります。ある時点で、比較的小さい数値と比較的大きい数値を最後に向かって組み合わせています。マシン精度の定義を思い出すと1 + e = 1、ある時点で操作で重要なビットが失われます。

うまくいけば、これは素人の言葉で明確にするのに役立ちます

于 2010-05-07T01:55:43.000 に答える
1

これは浮動小数点数の問題です。浮動小数点数は近似値であり、ゼロでは奇妙なことが起こります (つまり、奇妙な表現が現れます)。このため、当然のことと思っている数値操作の一部は、より繊細に処理する必要があります。

2 つの数値を比較する場合、 getおよびに適用される浮動小数点演算に沿って精度が失われるため、一方がそうであり、他方a == bがそうである可能性があるため、単純に言うことはできません。次のように、任意の許容範囲を選択する必要があります。0-1.03583e-13abfabs(a,b) < 1e-8

数値を印刷する場合、印刷する桁数を制限する必要があることがよくあります。を使用するprintfprintf("%g\n", a);、 のようなものは出力されません-1.03583e-13iostreamに類似したものがあるかどうかはわかりません%g。ある?

于 2010-05-07T01:39:53.303 に答える