Eliminate the baroque floating-point operators a la !<>=

dsimcha dsimcha at yahoo.com
Sun May 17 10:30:00 PDT 2009


== Quote from Andrei Alexandrescu (SeeWebsiteForEmail at erdani.org)'s article
> Hello,
> I think the floating-point operators:
>    a !<>= b
>    a !<> b
>    a <> b
>    a <>= b
>    a !> b
>    a !>= b
>    a !< b
>    a !<= b
> are useless. A simple peephole optimization in the compiler can
> automatically rewrite NaN test followed by regular operations into the
> operations above, for example:
> isNaN(a) || isNan(b) || a >= b
> is the same as
> a !< b
> This is in keeping with what the compiler does when seeing code like:
> a = x / y;
> b = x % y;
> There's a peephole optimization that groups the / and the % together
> into an assembler operation that does both. If this is the way to go, we
> better be congruent and use explicit isNaN tests (that are then
> optimized) instead of defining eight extra operators.
> Andrei

I personally would like to see the whole NaNs not having a defined ordering thing
done away with entirely.  This probably won't happen b/c it's (I would guess) in
the IEEE standard.  However, the fact that a NaN is not less than, equal to, or
greater than, anything creates an extremely annoying special case when doing
generic programming for anything that requires a total ordering, such as trees and
sorting.

Sorting, trees, etc. require a consistent total ordering, and NaNs mean that,
technically, floating point numbers don't have one.  This means that any generic
tree or sorting code that doesn't deal with this as a special case somehow is
technically broken, or, if you look at it differently, these algorithms are
invalid for floating point numbers.  For example, try the following code in
release mode (in debug mode, an assert fails).

import std.stdio, std.algorithm, std.random;

void main() {
    double[] foo = new double[20];
    foreach(i, ref elem; foo) {
        elem = (i & 1) ? double.nan : i;
    }
    randomShuffle(foo);
    sort(foo);
    writeln(foo);
}

This is enough of a corner case that, in most of the generic code I write, I
consider anything that expects a total ordering to just have completely undefined
behavior when there isn't one, but this is obviously not an optimal solution.  I
actually prefer not to know what some of my code does when given a range of floats
with a bunch of NaNs.



More information about the Digitalmars-d mailing list