What is the rationale for all comparisons returnin

2018-12-31 01:53发布

Why do comparisons of NaN values behave differently from all other values? That is, all comparisons with the operators ==, <=, >=, <, > where one or both values is NaN returns false, contrary to the behaviour of all other values.

I suppose this simplifies numerical computations in some way, but I couldn't find an explicitly stated reason, not even in the Lecture Notes on the Status of IEEE 754 by Kahan which discusses other design decisions in detail.

This deviant behavior is causing trouble when doing simple data processing. For example, when sorting a list of records w.r.t. some real-valued field in a C program I need to write extra code to handle NaN as the maximal element, otherwise the sort algorithm could become confused.

Edit: The answers so far all argue that it is meaningless to compare NaNs.

I agree, but that doesn't mean that the correct answer is false, rather it would be a Not-a-Boolean (NaB), which fortunately doesn't exist.

So the choice of returning true or false for comparisons is in my view arbitrary, and for general data processing it would be advantageous if it obeyed the usual laws (reflexivity of ==, trichotomy of <, ==, >), lest data structures which rely on these laws become confused.

So I'm asking for some concrete advantage of breaking these laws, not just philosophical reasoning.

Edit 2: I think I understand now why making NaN maximal would be a bad idea, it would mess up the computation of upper limits.

NaN != NaN might be desirable to avoid detecting convergence in a loop such as

while (x != oldX) {
    oldX = x;
    x = better_approximation(x);
}

which however should better be written by comparing the absolute difference with a small limit. So IMHO this is a relatively weak argument for breaking reflexivity at NaN.

13条回答
像晚风撩人
2楼-- · 2018-12-31 02:23

Very short answer:

Because the following: nan / nan = 1 must NOT hold. Otherwise inf/inf would be 1.

(Therefore nan can not be equal to nan. As for > or <, if nan would respect any order relation in a set satisfying the Archimedean property, we would have again nan / nan = 1 at the limit).

查看更多
骚的不知所云
3楼-- · 2018-12-31 02:25

From the wikipedia article on NaN, the following practices may cause NaNs:

  • All mathematical operations> with a NaN as at least one operand
  • The divisions 0/0, ∞/∞, ∞/-∞, -∞/∞, and -∞/-∞
  • The multiplications 0×∞ and 0×-∞
  • The additions ∞ + (-∞), (-∞) + ∞ and equivalent subtractions.
  • Applying a function to arguments outside its domain, including taking the square root of a negative number, taking the logarithm of a negative number, taking the tangent of an odd multiple of 90 degrees (or π/2 radians), or taking the inverse sine or cosine of a number which is less than -1 or greater than +1.

Since there is no way to know which of these operations created the NaN, there is no way to compare them that makes sense.

查看更多
看淡一切
4楼-- · 2018-12-31 02:26

NaN can be thought of as an undefined state/number. similar to the concept of 0/0 being undefined or sqrt(-3) (in the real number system where the floating point lives).

NaN is used as a sort of placeholder for this undefined state. Mathematically speaking, undefined is not equal to undefined. Neither can you say an undefined value is greater or less than another undefined value. Therefore all comparisons return false.

This behaviour is also advantageous in the cases where you compare sqrt(-3) to sqrt(-2). They would both return NaN but they are not equivalent even though they return the same value. Therefore having equality always returning false when dealing with NaN is the desired behaviour.

查看更多
情到深处是孤独
5楼-- · 2018-12-31 02:26

I don't know the design rationale, but here's an excerpt from the IEEE 754-1985 standard:

"It shall be possible to compare floating-point numbers in all supported formats, even if the operands' formats differ. Comparisons are exact and never overflow nor underflow. Four mutually exclusive relations are possible: less than, equal, greater than, and unordered. The last case arises when at least one operand is NaN. Every NaN shall compare unordered with everything, including itself."

查看更多
萌妹纸的霸气范
6楼-- · 2018-12-31 02:28

Because mathematics is the field where numbers "just exist". In computing you must initialize those numbers and keep their state according to your needs. At those old days memory initialization worked in the ways you could never rely on. You never could allow yourself to think about this "oh, that would be initialized with 0xCD all the time, my algo will not broke".

So you need proper non-mixing solvent which is sticky enough to not not letting your algorithm getting sucked into and broken. Good algorithms involving numbers are mostly going to work with relations, and those if() relations will be omitted.

This is just grease which you can put into new variable at creation, instead of programming random hell from computer memory. And your algorithm whatever it is, will not break.

Next, when you still suddenly finding out that your algorithm is producing NaNs, it is possible to clean it out, looking into every branch one at a time. Again, "always false" rule is helping a lot in this.

查看更多
旧人旧事旧时光
7楼-- · 2018-12-31 02:29

For me, the easiest way to explain it is:

I have something and if it is not an apple then is it an orange?

You can't compare NaN with something else (even itself) because it does not have a value. Also it can be any value (except a number).

I have something and if it is not equal to a number then is it a string?

查看更多
登录 后发表回答