Search code examples
c++doubleequals-operator

float and double constant comparing


From http://www.cprogramming.com/tips/tip/difference-between-float-and-double:

In c++ any value like 4.12 is treated as a double by default. Comparing floats and doubles can be a tricky business because of the difference in precision leading to minute errors. For example:

float a = 4.12;

if(a == 4.12)
{
    cout << "hello";
}
else
{
    cout << "bye";
}

This will show you the output as "bye 4.12"

Why?

Because by default 4.12 is a double (such as in the if statement or in the assignment to our variable), but storing it in a float it loses some precision, and so comparing then comparing a double with a float lead to microscopic changes in the precision of the number--remember that floats and doubles are not precise.

Two lessons here: one is that floating point numbers shouldn't be compared directly most of the time, and the other is that the default size and type of a hard-coded floating point number is double.

The thing is 'you should not do comparing float variable and double constant'.

So my question is that comparing float variable and float constant followed by 'f' is ok?

Something like this.

if(a == 4.12f)

Solution

  • comparing float variable and float constant followed by 'f' is ok?

    It's still dangerous. Unlike your float/double example which may well fail for every possible value of a, there is actually one value of a for which a == 4.12f will be true, but depending on how you set a it may not match 4.12f even when you expect it to. For example:

    #include <iostream>
    #include <iomanip>
    
    int main()
    {
        float f = 4.14;
        f -= 0.01;
        f -= 0.01;
        std::cout << std::boolalpha << (f == 4.12f) << '\n';
    }
    

    On ideone.com here this outputs:

    false
    

    The Standard does guarantee that the closest representation will be used in certain circumstances, so if you directly assign float a = 4.12f; then afterwards a == 4.12f will necessarily be true, and § 26.5.1.4 guarantees that if you stream out a and stream the text back in to another float they will compare equals afterwards.

    Anyway, if you feel you must depend on something like this, check the Standard/docs for the specific usage you're contemplating.