I had a small WTF moment this morning. Ths WTF can be summarized with this:
float x = 0.2f;
float y = 0.1f;
float z = x + y;
assert(z == x + y); //This assert is triggered! (Atleast with visual studio 2008)
The reason seems to be that the expression x + y
is promoted to double and compared with the truncated version in z
. (If i change z
to double
the assert isn't triggered).
I can see that for precision reasons it would make sense to perform all floating point arithmetics in double precision before converting the result to single precision. I found the following paragraph in the standard (which I guess I sort of already knew, but not in this context):
4.6.1.
"An rvalue of type float
can be converted to an rvalue of type double
. The value is unchanged"
My question is, is x + y
guaranteed to be promoted to double or is at the compiler's discretion?
UPDATE: Since many people has claimed that one shouldn't use ==
for floating point, I just wanted to state that in the specific case I'm working with, an exact comparison is justified.
Floating point comparision is tricky, here's an interesting link on the subject which I think hasn't been mentioned.
Using gcc 4.3.2, the assertion is not triggered, and indeed, the rvalue returned from
x + y
is afloat
, rather than adouble
.So it's up to the compiler. This is why it's never wise to rely on exact equality between two floating point values.
The Working draft for the next standard C++0x section 5 point 11 says
So at the compiler's discretion.
The C++ FAQ lite has some further discussion on the topic:
It is the problem since float number to binary conversion does not give accurate precision.
And within
sizeof(float)
bytes it cant accomodate precise value of float number and arithmetic operation may lead to approximation and hence equality fails.See below e.g.
I would think it would be at the compiler's discretion, but you could always force it with a cast if that was your thinking?
Yet another reason to never directly compare floats.