www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Dump special floating point operators

reply Walter Bright <newshound1 digitalmars.com> writes:
!<>=
<>
<>=
!<=
!<
!>=
!>
!>=

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
Dec 03 2009
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Walter Bright wrote:
 !<>=
 <>
 <>=
 !<=
 !<
 !>=
 !>
 !>=
 
 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
Dec 03 2009
next sibling parent reply ZY.Zhou <rinick goozo.net> writes:
Andrei Alexandrescu Wrote:
 
 a peephole optimization can detect isnan(a) || a < b and have it 
 translate into one instruction, same as a !>= b,

I think most people would use !(a>=b) rather than isnan(a) || isnan(b) || a < b
Dec 03 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
ZY.Zhou wrote:
 Andrei Alexandrescu Wrote:
 a peephole optimization can detect isnan(a) || a < b and have it 
 translate into one instruction, same as a !>= b,

I think most people would use !(a>=b) rather than isnan(a) || isnan(b) || a < b

Sorry. So a !>= b is indeed semantically equivalent with isnan(a) || isnan(b) || a < b. However, if I read the table at http://www.digitalmars.com/d/2.0/expression.html#RelExpression correctly, !(a >= b) would throw if either is NaN. Andrei
Dec 03 2009
parent reply ZY.Zhou <rinick goozo.net> writes:
Andrei Alexandrescu Wrote:
 Sorry. So a !>= b is indeed semantically equivalent with isnan(a) || 
 isnan(b) || a < b. However, if I read the table at 
 http://www.digitalmars.com/d/2.0/expression.html#RelExpression 
 correctly, !(a >= b) would throw if either is NaN.
 

But there is a note under that table:
 "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.

So I don't feel any difference between !(a>=b) and a!>=b
Dec 03 2009
parent reply Don <nospam nospam.com> writes:
ZY.Zhou wrote:
 Andrei Alexandrescu Wrote:
 Sorry. So a !>= b is indeed semantically equivalent with isnan(a) || 
 isnan(b) || a < b. However, if I read the table at 
 http://www.digitalmars.com/d/2.0/expression.html#RelExpression 
 correctly, !(a >= b) would throw if either is NaN.

But there is a note under that table:
 "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.
Dec 04 2009
parent Don <nospam nospam.com> writes:
Phil Deets wrote:
 On Fri, 04 Dec 2009 11:06:31 -0500, Don <nospam nospam.com> wrote:
 
 
 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.

Isn't a!<>b equivalent to (a!=a) || (b!=b) || (a==b)?

Yes.
Dec 04 2009
prev sibling next sibling parent "Phil Deets" <pjdeets2 gmail.com> writes:
On Fri, 04 Dec 2009 11:06:31 -0500, Don <nospam nospam.com> wrote:


 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.

Isn't a!<>b equivalent to (a!=a) || (b!=b) || (a==b)? -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Dec 04 2009
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 04 Dec 2009 21:15:39 -0500, Don <nospam nospam.com> wrote:

 Phil Deets wrote:
 On Fri, 04 Dec 2009 11:06:31 -0500, Don <nospam nospam.com> wrote:

 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.


Yes.

After reading this whole thread.. yes please dump this :) -Steve
Dec 05 2009
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter Bright:
 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
Dec 03 2009
parent KennyTM~ <kennytm gmail.com> writes:
On Dec 4, 09 13:16, bearophile wrote:
 Walter Bright:
 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

Actually you could easily "overload" them with opCmp, you just need to return a float. class NonComparable { float opCmp(NonComparable other) { return float.nan; } }; void main () { auto a = new NonComparable; assert(a !<>= a); }
Dec 03 2009
prev sibling parent reply Don <nospam nospam.com> writes:
Walter Bright wrote:
 !<>=
 <>
 <>=
 !<=
 !<
 !>=
 !>
 !>=
 
 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.
Dec 04 2009
parent reply Sean Kelly <sean invisibleduck.org> writes:
Don Wrote:
 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.

Doesn't x!=x work just as well?
Dec 04 2009
parent Don <nospam nospam.com> writes:
Sean Kelly wrote:
 Don Wrote:
 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.

Doesn't x!=x work just as well?

Dec 04 2009