NoobOverflow NoobOverflow - 1 year ago 86
Objective-C Question

"-Weverything" yielding "Comparing floating point with == or != is unsafe"

I have a string that I convert to a double like this:

double d = [string doubleValue];

The documentation for
tells us that upon overflow, this method returns either
. This is how I checked for this earlier:

if (d == HUGE_VAL || d == -HUGE_VAL)

Now, since adding the new "-Weverything" warning flag, the compiler now complains that

Comparing floating point with == or != is unsafe

How can I resolve this issue? How should I be doing these comparisons?

I also have the same question about comparing two "normal" floating point numbers (i.e. not "HUGE_VAL" ones). For instance,

double a, b;
if (a != b) //this will now yield the same warning

How should this be resolved?

Answer Source

You do not need to worry about this warning. It is nonsense in a lot of cases, including yours.

The documentation of doubleValue does not say that it returns something close enough to HUGE_VAL or -HUGE_VAL on overflow. It says that it returns exactly these values in case of overflow.

In other words, the value returned by the method in case of overflow compares == to HUGE_VAL or -HUGE_VAL.

Why does the warning exist in the first place?

Consider the example 0.3 + 0.4 == 0.7. This example evaluates to false. People, including the authors of the warning you have met, think that floating-point == is inaccurate, and that the unexpected result comes from this inaccuracy.

They are all wrong.

Floating-point addition is “inaccurate”, for some sense of inaccurate: it returns the nearest representable floating-point number for the operation you have requested. In the example above, conversions (from decimal to floating-point) and floating-point addition are the causes of the strange behavior.

Floating-point equality, on the other hand, works pretty much exactly as it does for other discrete types. Floating-point equality is exact: except for minor exceptions (the NaN value and the case of +0. and -0.), equality evaluates to true if and only if the two floating-point numbers under consideration have the same representation.

You don't need an epsilon to test if two floating-point values are equal. And, as Dewar says in substance, the warning in the example 0.3 + 0.4 == 0.7 should be on +, not on ==, for the warning to make sense.

Lastly, comparing to within an epsilon means that values that aren't equal will look equal, which is not appropriate for all algorithms.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download