!<>=
<>
<>=
!<=
!<
!>=
!>
!>=
http://www.digitalmars.com/d/2.0/expression.html#RelExpression
While I like them a lot, it's time for them to go:
1. It's hard to remember which one does what
2. They've failed to catch on
3. No operator overloading for them
4. They are only rarely needed; a special operator is not justified

!<>=
<>
<>=
!<=
!<
!>=
!>
!>=
http://www.digitalmars.com/d/2.0/expression.html#RelExpression
While I like them a lot, it's time for them to go:
1. It's hard to remember which one does what
2. They've failed to catch on
3. No operator overloading for them
4. They are only rarely needed; a special operator is not justified

(per our discussion)
5. a peephole optimization can detect isnan(a) || a < b and have it
translate into one instruction, same as a !>= b, thus addressing the
efficiency problem that the FP operators were meant to solve.
Peephole optimizations have a precedent:
c = a / b;
d = a % b;
only use one division-and-remainder instruction.
Andrei

"Exception" means the Invalid Exception is raised if one of the
operands is a NAN. It does not mean an exception is thrown.
Invalid Exception can be checked using the functions in std.c.fenv.

If a or b is signalling NaN (uninitialized variable), and invalid
exceptions are unmasked, then a!>=b will generate a hardware exception
-- showing you that you used an uninitialized variable.
isnan(a) || isnan(b) || a < b
will not raise the hardware exception.

So I don't feel any difference between !(a>=b) and a!>=b

There's no difference between !(a>=b) and a!>=b.
Here's a table of equivalences.
a!<>=b (a!=a) || (b!=b)
a<>b (a==a) && (b==b) && (a!=b)
a!<>b (a!=a) || (b!=b) || (a!=b)
a<>=b (a==a) && (b==b)
a!<=b !(a<=b)
a!<b !(a<b)
a!>=b !(a>=b)
a!>b !(a>b)
a!>=b !(a>=b)
Obviously if a or b is known at compile time, or if it is known not to
be NaN, many of the <> clauses can be dropped.

Here's a table of equivalences.
a!<>=b (a!=a) || (b!=b)
a<>b (a==a) && (b==b) && (a!=b)
a!<>b (a!=a) || (b!=b) || (a!=b)
a<>=b (a==a) && (b==b)
a!<=b !(a<=b)
a!<b !(a<b)
a!>=b !(a>=b)
a!>b !(a>b)
a!>=b !(a>=b)
Obviously if a or b is known at compile time, or if it is known not to
be NaN, many of the <> clauses can be dropped.

Here's a table of equivalences.
a!<>=b (a!=a) || (b!=b)
a<>b (a==a) && (b==b) && (a!=b)
a!<>b (a!=a) || (b!=b) || (a!=b)
a<>=b (a==a) && (b==b)
a!<=b !(a<=b)
a!<b !(a<b)
a!>=b !(a>=b)
a!>b !(a>b)
a!>=b !(a>=b)
Obviously if a or b is known at compile time, or if it is known not to
be NaN, many of the <> clauses can be dropped.

Here's a table of equivalences.
a!<>=b (a!=a) || (b!=b)
a<>b (a==a) && (b==b) && (a!=b)
a!<>b (a!=a) || (b!=b) || (a!=b)
a<>=b (a==a) && (b==b)
a!<=b !(a<=b)
a!<b !(a<b)
a!>=b !(a>=b)
a!>b !(a>b)
a!>=b !(a>=b)
Obviously if a or b is known at compile time, or if it is known not to
be NaN, many of the <> clauses can be dropped.

While I like them a lot, it's time for them to go:
1. It's hard to remember which one does what
2. They've failed to catch on
3. No operator overloading for them
4. They are only rarely needed; a special operator is not justified

Before trashing everything some useful compromise between the two extrema
(having many complex operators, and having nothing) can be found. I think Don
said something about this.
Regarding "no operator overloading for them", it's a matter of will, with the
opBinary operator syntax it's easy to use them too :-)
Bye,
bearophile

While I like them a lot, it's time for them to go:
1. It's hard to remember which one does what
2. They've failed to catch on
3. No operator overloading for them
4. They are only rarely needed; a special operator is not justified

Before trashing everything some useful compromise between the two extrema
(having many complex operators, and having nothing) can be found. I think Don
said something about this.
Regarding "no operator overloading for them", it's a matter of will, with the
opBinary operator syntax it's easy to use them too :-)
Bye,
bearophile

!<>=
<>
<>=
!<=
!<
!>=
!>
!>=
http://www.digitalmars.com/d/2.0/expression.html#RelExpression
While I like them a lot, it's time for them to go:
1. It's hard to remember which one does what
2. They've failed to catch on
3. No operator overloading for them
4. They are only rarely needed; a special operator is not justified

I think I've used them more than anyone else, and I agree. What I've
noticed is that you _always_ want to treat NaNs as a special case. In
asm, you can have a 3-way branch: eg,
cmp a, b;
jp L_nan;
jl L_less;
Lgreater_eq: // a >= b
L_less: // a < b
L_nan: // a or b is NaN.
But the NCEG operators don't let you do that. They only allow you to
chose which way NaNs should go. In almost all cases, you can replace
a!>b with !(a<=b), so the cases where they are beneficial are very, very
limited.
Currently one use is in CTFE:
isNaN(x) doesn't work in CTFE at the moment, whereas x<>=0 does. But of
course isNaN should work in CTFE.