Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
432 views
in Technique[技术] by (71.8m points)

objective c - "-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 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...