0

I am having quite an ununderstable problem here. I want my x value to get from 0.0 to 1.0, increasing by 0.05.

It seems like a quite eazy thing to do. However, at the end of my loop when evaluating x <= L ( with x = 1.0 and L = 1.0) I get a 0 value.

I also tried hard writing L, It does not change the behaviour.

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;
}

At the end of the code you can see some printing test that I have performed.

Normally all of those test results should be 1.

Does anyone has an idea of how and why the test doesn't pass ?

Yoann
  • 43
  • 6
  • this was closed as dupe of [is floating point math broken](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) I reopened it because this is not about floating point. Please **read the question** and my answer before voting to close – bolov Oct 30 '17 at 00:19
  • Possible duplicate of [Floating point loop runs more iterations than should be](https://stackoverflow.com/questions/20001912/floating-point-loop-runs-more-iterations-than-should-be) – Raymond Chen Oct 30 '17 at 00:23
  • @RaymondChen that is also about precision. This problem has **nothing to do with precision**. Replace all double/float with `int` in the post and you would observe the same problem. – bolov Oct 30 '17 at 00:25

2 Answers2

2

This is not about floating point precision. You have a flaw in your logic deduction.

Normally all of those test results should be 1

No they shouldn't. This is what you have:

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

x <= L should be and is false because that's when the while loop is broken.

Think about it. If you have while( x <= L) then while the condition is true, the while repeats. It is only when this condition gets false you end the while loop and get out of it. So when you exit the while you know for sure 100% that x <= L is false. Otherwise it would still have looped.

So yes, naturally, all of these conditions x <= L x <= 1.0 are false when you get out of loop.


For those still thinking this is about floating precision: it is not. His code and problem is equivalent with this code that uses int. No floating point in sight:

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

The OP is basically saying x <= L should be true. But it obviously isn't for the reasons exposed above.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • Yes I agree that his loop ended after `x<=L` but your answer doesn't justify why is it that he is still getting 1 as the value for both `L` and `x` and still getting 0 for `x<=L`. I ran a quick test online and yes, this indeed is because of floating point precision. – Parijat Purohit Oct 30 '17 at 05:05
-1

It is not quite uncommon to experience this with double.

The values stored in double aren't stored with much precision (Think of how you could you do a binary representation of a decimal).

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

This is the reason why you get a value slightly greater than L in your last iteration, because of which, your equality doesn't hold true.

Probably, to check what the exact value is, which is getting compared, you can set the precision level of cout to something like 20 by doing cout.precision(20);.

On adding this and running your code again, following is the output which I received on an online compiler:

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

Yes, your loop did break because of the fact that x<=L returned false but x didn't assume a value of 1.05, which I think is what you were expecting.

Parijat Purohit
  • 921
  • 6
  • 16