Yoann
Yoann

Reputation: 43

c++ <= operator does not seems to be working

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 ?

Upvotes: 0

Views: 104

Answers (2)

Parijat Purohit
Parijat Purohit

Reputation: 921

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.

Upvotes: -1

bolov
bolov

Reputation: 75874

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.

Upvotes: 2

Related Questions