On Tuesday, 12 November 2013 at 19:26:12 UTC, tn wrote:
But 'a<b' is transitive for floating points. The transitivity
condition (`a<b && b<c` implies `a<c`) says nothing about the
cases where a and b (or b and c) are incomparable. Transitivity
is not the problem
Whoops, you're right. I meant transitivity of the negated
expression: !(a>b) && !(b>c) implies !(a>c). This fails for [3,
NaN, 1].
Sort et al don't know how to check "a>=b"... and they can't
use "a<b" either, because !(a<b) && !(b<a) implies a==b.
This is the problem, that is, the fact that with '<' you can't
tell the difference between equal values and incomparable
values (one or both are NaNs). On the other hand, with '<=' you
can. See:
(a<b) && !(b<a) --> a<b
!(a<b) && (b<a) --> b<a
(a<b) && (b<a) --> (not possible)
!(a<b) && !(b<a) --> a==b OR incomparable
but
(a<=b) && !(b<=a) --> a<b
!(a<=b) && (b<=a) --> b<a
(a<=b) && (b<=a) --> a==b
!(a<=b) && !(b<=a) --> incomparable
Thus, the correct solution would be to modify the functions to
take "lessOrEqual" as a template parameter instead of "less".
Too late for that now... just like it's too late to change IEEE
comparison logic.
If "less" is kept, then we need another template argument to
separate equality and incomparability (something like
"equals(a,b)", or "incomparable(a,b)").
Is this to allow generic partial ordering (rather than to fix
sorting NaNs specifically)? I remember seeing a thread about
partial ordering and opCmp:
http://forum.dlang.org/post/[email protected]