TL;DR Do the IEEE754 floating point values including NaN
satisfy LessThanComparable
?
Specifically, question "Why does Release/Debug have a different result for std::min?" got me looking up LessThanComparable
:
The type must work with < operator and the result should have standard semantics.
Requirements
The type T satisfies LessThanComparable if
Given
- a, b, and c, expressions of type T or const T
The following expressions must be valid and have their specified effects
Establishes strict weak ordering relation with the following properties (...)
I double checked it in the standard and it seems it states basically the same there, and I looked at the Wikipedia def of strict weak ordering.
Some think that the set of IEEE floating point vales that includes NaN does not satisfy this concept: Any comparison with NaN on either side will always yield false, but I have been looking at the definitions, and it is not at all apparent to me whether the presence of NaN
breaks strict weak ordering:
For the list given at Wikipedia:
- For all x in S, it is not the case that x < x (irreflexivity).
- For all x, y in S, if x < y then it is not the case that y < x (asymmetry).
see below
- For all x, y, z in S, if x < y and y < z then x < z (transitivity).
- For all x, y, z in S, if x is incomparable with y (neither x < y nor y < x hold), and y is incomparable with z, then x is incomparable with z (transitivity of incomparability).
It seems that the strict weak ordering axiom as defined on Wikipedia explicitly calls out possible incomparable
values: NaN seems a good candidate here?
On the other hand, the standard says: (25.5/4)
If we define
equiv(a, b)
as!comp(a, b) && !comp(b, a)
, then the requirements are that comp and equiv both be transitive relations:(4.1) —
comp(a, b) && comp(b, c)
impliescomp(a, c)
(4.2) —
equiv(a, b) && equiv(b, c)
impliesequiv(a, c)
With these definitions, equiv(x, NaN)
is always true
(because !comp(a, NaN)==true
and !comp(Nan, a)==true
: comparison with Nan yields false, negation then yields true)
But clearly (4.2) is not satisfied, e.g:
equiv(3.0, NaN) && equiv(NaN, 7.0) **does not** imply equiv(3.0, 7.0)
So is what the standard defines not a Strict Weak Ordering, or -- more likely indeed -- am I missing something here?