Weird bug in C++, boolean expression evaluates to true when should be false?

So I was running this code, working with this big number. Note a and b are exactly the same. (scroll right if code doesn’t fit screen)

#include <bits/stdc++.h>

using namespace std;

int main() {
	long long a = 298023223876953125, b = 298023223876953125;
	cout << boolalpha << (a <= (floor(298023223876953125 / 2) * 2)) << '\n'; //1
	cout << boolalpha << (a <= (floor(298023223876953125 / 4) * 4)) << '\n'; //2
	cout << boolalpha << (a <= (floor(298023223876953125 / 8) * 8)) << '\n'; //3
	cout << boolalpha << (b >= (floor(298023223876953125 / 2) * 2)) << '\n'; //1
	cout << boolalpha << (b >= (floor(298023223876953125 / 4) * 4)) << '\n'; //2
	cout << boolalpha << (b >= (floor(298023223876953125 / 8) * 8)) << '\n'; //3
	cout << "a: " << a << ", " << "after operation: " << (long long)(floor(298023223876953125 / 2) * 2) << '\n';
	cout << "a: " << a << ", " << "after operation: " << (long long)(floor(298023223876953125 / 4) * 4) << '\n';
	cout << "a: " << a << ", " << "after operation: " << (long long)(floor(298023223876953125 / 8) * 8) << '\n';
}

The output was
true

true

false

true

true

true

a: 298023223876953125, after operation: 298023223876953152

a: 298023223876953125, after operation: 298023223876953152

a: 298023223876953125, after operation: 298023223876953088

which was unexpected with a and b exactly the same. From the comments at the end of the lines with the inequalities, i have labelled corresponding ones with the same number, 1 2 or 3. The combination of the 2 inequalities both labelled, for example, //1 are both satisfied iff after operation the number is exactly a or b, as the only way it is between both a and b is if it has the same value as a or b.
Is there some stupid thing I’m overlooking here (probably is)? Thank you

floor() actually returns double data type. You can check Floor function C++. You could also verify it using typeid().name() function, which outputs d indicating the data type returned from floor() is actually double and not long long. You should always remember that double or float or even long double has precision errors in the order of 10^-15. Hence, the values of double in cannot be treated as accurate since there can be some precision errors. Hence you should never perform operations in floating-point numbers if small precision errors could also change the answers, like in your example.

1 Like

Ah I’ve got it now, I have instead used a long long cast and that works as expected. thanks (: