Spaceship Operator on NaN
Asked Answered
E

1

9

How does C++ treat floating-point NaN when doing space-ship comparison operations? We know that the usual compares always return false, so how does this change with NaN?

std::numeric_limits<double>::quiet_NaN() <=> std::numeric_limits<double>::quiet_NaN()
Emden answered 30/6, 2020 at 0:7 Comment(1)
A
9

According to cppreference, in the case of floating point arguments to the built-in <=> operator:

[...] the operator yields a prvalue of type std::partial_ordering. The expression a <=> b yields

  • std::partial_ordering::less if a is less than b
  • std::partial_ordering::greater if a is greater than b
  • std::partial_ordering::equivalent if a is equivalent to b (-0 <=> +0 is equivalent)
  • std::partial_ordering::unordered (NaN <=> anything is unordered)

So, in brief, applying <=> to a floating point value of NaN results in std::partial_ordering::unordered.

When evaluating an expression like a <=> b == 0 or a <=> b < 0, if either a or b is NaN then the whole expression returns false, which makes sense coming from NaN's built-in behaviour (source). Of course, std::partial_ordering::unordered == std::partial_ordering::unordered holds true or else this type wouldn't be very useful.

If you can otherwise guarantee the absence of pathological floating point values, take a look at this Q/A for a floating point wrapper whose comparisons yield std::strong_ordering.

Antibes answered 30/6, 2020 at 0:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.