Well you are a victim of finite precision floating point arithmetic.
What happened?
This if(insideDbl == indexDbl)
, is very dangerous and misleading. It is in fact a question whether (Note: I made up the exact numbers but I can give you precise ones) 3.00000000000001255
is the same as 2.999999999999996234
. I put 14 0
s and 14 9
s. So technically the difference goes beyond 15 most significant places. This is important.
Now if you write insideDbl == indexDbl
, the compiler compares the binary representantions of them. Which are clearly different. However, when you simply print them, the default precision is like 5 or 6 significant digits, so they get rounded, and seem to be the same.
How to check it?
Try printing them with:
typedef std::numeric_limits< double > dbl_limits;
cout.precision(dbl::max_digits10);
cout << "Does " << insideDbl << " == " << indexDbl << "?\n";
This will set the precision, to the number of digits, the are necessary to differentiate two numbers. Please note that this is higher than the guaranteed precision of computation! That is the root of confusion.
I would also encourage reading numeric_limits. Especially about digits10
, and max_digits10
.
Why sometimes it works?
Because sometimes two algorithms will end up using the same binary representation for the final results, and sometimes they won't.
Also 2
can be a special case, as I believe it can be actually represented exactly in binary form. I think (but won't put my head on it.) all powers of 2 (and their sums) can be, like 0,675 = 0,5+0,125 = 2^-1 + 2^-3
. But please don't take it for granted unless someone else confirms it.
What can you do?
Stick to the precise computations. Using integers, or whatever. Or you could assume that everything 3.0 +/- 10^-10
is actually 3.0 (epsilon comparisons), which is very risky, to say the least, when you do care about precise math.
Tl;dr: You can never compare two float
s or double
s for equality, even when mathematically you can prove the mentioned equality, because of the finite precision of computations. That is, unless you are actually interested in the same binary representation of the value, as opposed to the value itself. Sometimes this is the case.