I have a string that I convert to a double like this:
double d = [string doubleValue];
The documentation for doubleValue
tells us that upon overflow, this method returns either HUGE_VAL
or -HUGE_VAL
. This is how I checked for this earlier:
if (d == HUGE_VAL || d == -HUGE_VAL) //overflow
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?
In the case of floating-point numbers, the relational operator (==) does not produce correct output, this is due to the internal precision errors in rounding up floating-point numbers.
To compare two floating point or double values, we have to consider the precision in to the comparison. For example, if two numbers are 3.1428 and 3.1415, then they are same up to the precision 0.01, but after that, like 0.001 they are not same.
How To Compare Floats in Python. If abs(a - b) is smaller than some percentage of the larger of a or b , then a is considered sufficiently close to b to be "equal" to b . This percentage is called the relative tolerance. You can specify the relative tolerance with the rel_tol keyword argument of math.
Float has to round more than double, because it is smaller, so 1.1 rounded to the nearest valid Float is different to 1.1 rounded to the nearest valud Double.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With