The Plan 9 C compilers do not appear to be compliant with the IEEE floating
point standard when making comparisons with NaN (not a number) values.

The standard says a comparison with one or both operands NaN is "unordered",
ie all relations evaluate to false, except != which is always true.

Testing with this fragment of code:
        double a, b;
        setfcr(0);
        a = 0.0;
        b = sqrt(-1.0);
        if(a <  b) print(" (a < b)");
        if(a <= b) print(" (a <= b)");
        if(a == b) print(" (a == b)");
        if(a != b) print(" (a != b)");
        if(a >= b) print(" (a >= b)");
        if(a >  b) print(" (a > b)");
        if(b <  a) print(" (b < a)");
        if(b <= a) print(" (b <= a)");
        if(b == a) print(" (b == a)");
        if(b != a) print(" (b != a)");
        if(b >= a) print(" (b >= a)");
        if(b >  a) print(" (b > a)");
        print("\n");
on ARM the result is almost completely wrong:
 (a < b) (a <= b) (a != b) (b < a) (b <= a) (b != a)
and on x86 the result is even wronger:
 (a < b) (a <= b) (a == b) (b < a) (b <= a) (b == a)
compared to the IEEE expected result, for example on MacOS:
 (a != b) (b != a)

This was discovered by fgb; I've been looking into the cause -- which is
mainly the assumption, in the compiler and linker, that something like this:
        if (a < b) f();
can safely be transformed to this:
        if (a >= b) goto skip;
        f();
        skip:
Unfortunately if a or b is NaN, the conditional will be false in both cases.

So is this a feature, or a bug that needs fixing?


Reply via email to