私は時間配列が必要な小さなODEソルバをプログラミングしていたとき、次のような本当に奇妙な動作に終わった。次のコードでは、問題を明確に再現する必要があります。<=と==演算子がループを終了するために正しく動作しない
#include <iostream>
using namespace std;
int main() {
double t = 0.0;
for (t = 0.0; t <= 1.00; t += 0.01) {
cout << t << " ";
}
cout << endl;
cout << "t = "<< t << " and t <= 1.00? " << (t <= 1.00) << endl;
double c = 1.00;
cout << "c = "<< c << " and c <= 1.00? " << (c <= 1.00) << endl;
cout << "t == 1.00? " << (t == 1.00) << " and c == 1.00? " << (c == 1.00) << endl;
return 0;
}
これは次のように出力できます:
0 0.01 0.02 0.03 0.04 ... 0.97 0.98 0.99
t = 1 and t <= 1.00? 0
c = 1 and c <= 1.00? 1
t == 1.00? 0 and c == 1.00? 1
私の質問は:tははっきり1と同じである必要がありながら、なぜ(トン< = 1.00)とさ(t == 1.00)がfalseを返すんをし、 tはdouble型ですか?
私は本当に私のT-ステップは、ハードなどをコード化されていない、私の実際のコードでは、この問題の原因を避けることができない...
は事前にありがとうございます。
編集:回答ありがとうございます。実際、0.01などのバイナリ表現の問題は正確ではなく、ある程度の丸め誤差を伴います。 tスケールは、プログラムの他の物理量によって実際に強制されました。その間に私が他に持っていた別の答え/ヒントは、浮動小数点メンバーを使って作業する必要がある場合、常に許容値で作業することでした。この場合、アプリケーションで必要とされるように可変精度hで作業する場合、「t < = 1.00」は「t < 1.00 + 0.01/2」またはより一般的な「t < 1.00 + h/2」になる可能性があります。
tobi303 @:偽得になっています。それが真であれば、ループは止まらないでしょう。 ( 'c <= 1.00'が真であるのは、' c!= t'のためです。) – user2357112
@ user2357112ええ、私はちょうど私の愚かさを認識しました。浮動小数点数がうまくいけないことを考慮すると、期待通りです。 – user463035818
'main'の最初に' cout.precision(17); 'を追加してみてください。問題は明らかになります。 )。累積誤差を四捨五入する小数点以下の桁数を表示しています。 –