Floating point comparison 0

If foo is of type float, is the following expression valid / recommended?

(0.0f == foo * float(0)) 

Will it have the expected (mathematical) value regardless of the value of foo?

Does the C ++ standard determine the behavior or specificity of its implementation?

+6
c ++ equality floating-point
source share
5 answers

Well, firstly, this is not a question of the C ++ standard. Rather, it's about your floating point model standard (most likely, IEEE).

For IEEE floats, this is probably safe, since float(0) should result in the same number as 0.0f, and the number multiplied by any other number should also be 0.0f.

What is unsafe is to do other floating point operations (for example: adding and subtracting a non-integer) and checking them for 0.0f.

+3
source share

AFAIK, it is not necessary, it can also be very close to 0.

It is usually best to compare with epsilon. I use this function to perform such comparisons:

 float EpsilonEqual( float a, float b, float epsilon ) { return fabsf( a - b ) < epsilon; } 
+2
source share

NaNs and Infinites can ruin such comparisons, as others have already mentioned.

However, there is another mistake: in C ++ you cannot rely on a compilation time expression of type float comparing it with the same expression that was evaluated at runtime.

The reason for this is that C ++ allows for extended fp precision in any way perforce. Example:

 #include <iostream> // This provides sufficent obfuscation so that g++ doesn't just inline results. bool obfuscatedTrue() { return true; } int main() { using namespace std; double const a = (obfuscatedTrue()? 3.0 : 0.3); double const b = (obfuscatedTrue()? 7.0 : 0.7); double const c = a/b; cout << (c == a/b? "OK." : "\"Wrong\" comparision result.") << endl; } 

Results with one specific compiler:

 C:\test> g++ --version | find "++" g++ (TDM-2 mingw32) 4.4.1 C:\test> g++ fp_comparision_problem.cpp & a "Wrong" comparision result. C:\test> g++ -O fp_comparision_problem.cpp & a OK. C:\test> _ 

Cheers and hth.,

- alf

+2
source share

With this specific statement, you can be sure that the result will be 0 , and the comparison will be true - I do not think that the C ++ standard prescribes it, but any reasonable implementation of floating-point types will have 0 works like this.

However, for most other calculations it cannot be expected that the result will be exactly equal to the letter of the mathematically correct result:

Why aren’t my numbers, for example, 0.1 + 0.2, making a good round of 0.3 and instead I get a strange result like 0.30000000000000004?

Because computers internally use a format (binary floating point) that cannot represent a number exactly, such as 0.1, 0.2, or 0.3.

When the code is compiled or interpreted, your "0.1" is already rounded to the nearest format, which leads to a small rounding error even before the calculation takes place.

Read the Floating Point Guide for detailed explanations and comparing with expected values .

+1
source share

I just read this article in msdn about the / fp option in VisualStudio link text

Optimization of expressions that are not valid for special values ​​(NaN, + infinity, -infection, +0, -0) will not be allowed. Optimizations xx => 0, x * 0 => 0, x-0 => x, x + 0 => x and 0-x => -x are not valid for different ones (see IEEE 754 and C99 standard).

0
source share

All Articles