13

Consider for example

bool fun (double a, double b) {
    return a < b;
}

What will fun return if any of the arguments are NaN? Is this undefined / implementation defined behavior?

What happens with the other relational operators and the equality operators?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • 3
    The answers to [this question](http://stackoverflow.com/questions/15268864/how-to-compare-two-nan-values-in-c) address it. (I borderline think that this question is a duplicate of that, BTW.) – Ami Tavory Jul 04 '15 at 21:39
  • 1
    @AmiTavory This answer only handles the equality case. – Baum mit Augen Jul 04 '15 at 21:40
  • @BaummitAugen http://stackoverflow.com/a/15268938/985296 – stefan Jul 04 '15 at 21:41
  • You might be right, but I read it otherwise. From what I understand from there, you can't compare it (in any way, not only equality) with anything. – Ami Tavory Jul 04 '15 at 21:41
  • @AmiTavory I feel like this interpretation would require some proof. – Baum mit Augen Jul 04 '15 at 21:42
  • @BaummitAugen Try reading again. Quoting the quote: "NaN is unordered: it is not equal to, greater than, or less than anything, including itself." – stefan Jul 04 '15 at 21:42
  • 1
    @stefan But does that mean the inequality comparison should be true, false, unspecified, or undefined? – juanchopanza Jul 04 '15 at 21:44
  • 1
    @juanchopanza I only claim that the linked answer makes a very specific claim, namely saying that any of such comparisons returns false. I didn't say that's the standard (because I didn't check yet, hence a comment, not an answer) – stefan Jul 04 '15 at 21:47

3 Answers3

20

Any comparison(except with "!=") with NaN returns false.

Here is a table I constructed:

     +Dbl_Nan  0_Nan  Inf_Nan  NaN_NaN  +Dbl_Inf  +Dbl_-Inf  Inf_-Inf  Inf_Inf
   -----------------------------------------------------------------------
>  |  False    False  False    False     False     True      True      False
<  |  False    False  False    False     True      False     False     False
== |  False    False  False    False     False     False     False     True
!= |  True     True   True     True      True      True      True      False

Click here for the Rationale on why NaN is always false.

Community
  • 1
  • 1
SunsetQuest
  • 8,041
  • 2
  • 47
  • 42
  • 1
    Nice link, upvoted. I will leave the accept on the other answer though as I feel it is more complete from the C++ point of view. – Baum mit Augen Jul 04 '15 at 22:24
16

The C++ standard merely says:

[expr.rel]/5 If both operands (after conversions) are of arithmetic or enumeration type, each of the operators shall yield true if the specified relationship is true and false if it is false.

So basically, a < b is true if a is less than b.

However, the implementation may claim conformance to IEC 559 aka IEEE 754 standard for floating point arithmetic, via numeric_limits::is_iec559. Then it is governed by that standard in section 5.7 and table 4, which requires that all comparisons but != involving NaN report false. != involving NaN reports true

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
  • 1
    So would the call invoke UB or not? – Baum mit Augen Jul 04 '15 at 21:47
  • 3
    It's hard to imagine an implementation that a) supports `NaN` values, but b) doesn't have them behave per IEEE 754. On any sane implementation, `a < b` is well-defined and has the value of `false` if either or both operands are `NaN`. The standard, however, is pretty vague on the topic - intentionally so, I believe, in order to cater to non-IEEE 754-conforming systems. – Igor Tandetnik Jul 04 '15 at 21:49
  • Can you make the IEEE part more rigorous? – Baum mit Augen Jul 04 '15 at 21:57
  • No, not really. I'm not all that familiar with that standard. If you think you need more information, please feel free to look it up. – Igor Tandetnik Jul 04 '15 at 22:03
1

False.

There is really no such thing as -NaN, although NaN values do carry a sign bit, as well as a payload. But for arithmetic purposes, a NaN is a NaN is a NaN.

Any equality or ordered comparison with a NaN is false.

rici
  • 234,347
  • 28
  • 237
  • 341