2017-10-29 6 views
0

ここではかなり不安定な問題が発生しています。 私はx value0.0 to 1.0から、0.05に増やしたいと思っています。C++ <=演算子が動作していないようです

これはかなり怠惰なことです。しかし、私のループの最後にと評価したときx <= L (with x = 1.0 and L = 1.0)私は0 valueを得る。

また、Lと書いてみました。は、動作が変更されません。コードの最後で

std::ofstream& operator<<(std::ofstream& ofs, Solver& s) { 

double x = 0.0; 
double L = 1.0; 
while(x <= L){ 
    //Do stuff related to my project 
    x += 0.05; 
} 
std::cout << "x= : " << x << std::endl;// 1 
std::cout << "L= : " << L << std::endl;// 1 
std::cout << "(x <= L)= : " << (x <= L) << std::endl;// 0 
std::cout << "(1 <= L)= : "<< (1 <= L) << std::endl;//1 
std::cout << "(1.0 <= L)= : "<< (1.0 <= L) << std::endl;//1 
std::cout << "(x <= 1)= : "<< (x <= 1) << std::endl;//0 
std::cout << "(x <= 1.0) : "<< (x <= 1.0) << std::endl;//0 
std::cout << "(1.0 <= 1)= : "<< (1.0 <= 1) << std::endl;//1 

} 
return ofs; 
} 

あなたは、私が行ってきたいくつかの印刷試験を見ることができます。

通常はこれらのすべてのテストの結果は1である必要があります。

どのように、なぜテストが合格しないのか、誰もが知っていますか?

+0

これは[浮動小数点数学が壊れています]のように閉じられました(https://stackoverflow.com/questions/588004/is-floating-point-math-broken)これは浮動小数点数ではないため再オープンしました。 **を閉じると投票する前に**の質問と私の答えをお読みください – bolov

+0

[浮動小数点ループの可能な複製より多くの反復が実行される可能性があります](https://stackoverflow.com/questions/20001912/floating-point-loop-runs -more-it-should-be-be) –

+0

@RaymondChenこれはまた、精度についてのものです。この問題は**精度とは関係ありません**。すべてのdouble/floatをポストの 'int'に置き換えれば、同じ問題が発生します。 – bolov

答えて

-1

これは二重では珍しくありません。

doubleに格納された値はあまり正確に格納されません(小数点のバイナリ表現の仕方を考えてください)。

double a = 1.1 * 3.1; 
cout <<a; //gives 3.4100000000000006 instead of 3.41 

そのうち、あなたの等式が成立していないので、これは、あなたがあなたの最後の反復でLよりも若干大きい値を得る理由です。

おそらく、比較されている正確な値が何であるかを確認するには、cout.precision(20);を実行して、coutの精度レベルを20に設定します。あなたのループがあるためx<=Lfalseが、xのdidn」が返さという事実を壊した、

x= : 1.000000000000000222 //what I was talking about 
L= : 1 
(x <= L)= : 0 //1.000000000000000222 is greater than 1 
(1 <= L)= : 1 //L is 1 
(1.0 <= L)= : 1 //L is 1 again 
(x <= 1)= : 0 //1.000000000000000222 is greater than 1 
(x <= 1.0) : 0 // 1.000000000000000222 is greater than 1.0 
(1.0 <= 1)= : 1 //this is pointless 

はい:これを追加して、もう一度あなたのコードを実行し、以下に

は、私がオンラインコンパイラで受信した出力でありますtは1.05の値を取ると思っています。

2

浮動小数点精度ではありません。論理控除に欠陥があります。

通常、これらすべてのテスト結果のはありません、彼らはいけない1

でなければなりません。

while(x <= L) { 
    // ... 
} 
std::cout << "(x <= L)= : " << (x <= L) << std::endl; // 0 

x <= Lが可能とwhileループが壊れているとき、それはだからfalseである必要があります。これは、あなたが持っているものです。

考えてみてください。条件が真である間にwhile(x <= L)がある場合、whileが繰り返されます。この状態が偽になった場合にのみ、whileループを終了して抜け出すことができます。したがって、whileを終了すると、確かに100%そのx <= Lであることがわかります。です。さもなければ、それはまだループしていました。

ループの外に出ると、自然にこれらの条件のすべてがx <= Lx <= 1.0になります。


これはまだ浮動小数精度について考えている人にとって、そうではありません。彼のコードと問題はintを使用するこのコードと同等です。浮動小数点なし:

int x = 0; 
int L = 100; 

while (x <= L) 
{ 
    //Do stuff related to my project 
    x += 5; 
} 

std::cout << "(x <= L)= : " << (x <= L) << std::endl; // 0 
std::cout << "(x <= 100)= : "<< (x <= 100) << std::endl; //0 

OPは基本的にはx <= Lが真であると言っています。しかし、明らかに上記の理由からではありません。

+0

はい私は彼のループが 'x <= L'の後で終わったことに同意しますが、あなたの答えはなぜ彼がまだ' L'と 'x'の両方の値として1を得ているのか、そして' x <= L 'となる。 オンラインでクイックテストを実行しましたが、これは実際には浮動小数点精度のためです。 –

関連する問題