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]

Reply via email to