www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - yank '>>>'?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
D has operator >>> which means "unsigned shift to the right", inherited 
from Java. But it doesn't need it because D has unsigned types, which 
can be used to effect unsigned shift. (Java, lacking unsigned types, had 
no other way around but to define a new operator.)

Should we yank operator>>>?


Andrei
Dec 06 2009
next sibling parent Ellery Newcomer <ellery-newcomer utulsa.edu> writes:
On 12/06/2009 10:11 AM, Andrei Alexandrescu wrote:
 D has operator >>> which means "unsigned shift to the right", inherited
 from Java. But it doesn't need it because D has unsigned types, which
 can be used to effect unsigned shift. (Java, lacking unsigned types, had
 no other way around but to define a new operator.)

 Should we yank operator>>>?


 Andrei
taking the opportunity to review what the difference is between >> and >>> for signed integers, >> is equivalent to divide by 2. It leaves the sign bit unchanged. >>> is an actual bit shift. Neither moves the lower n bits to the upper n bits or anything like that. for unsigned integers, >> is equivalent to divide by 2. >>> is an actual bit shift, but that's equivalent to divide by 2, so >> and >>> are the same. I've never liked that >> doesn't actually shift all of the bits, and the only valid use for it is equivalent to a / 2^^n except less readable. Although I don't suppose one should be doing bitwise manipulations with signed integers in the first place..
Dec 06 2009
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
Dec 06 2009
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from bearophile (bearophileHUGS lycos.com)'s article
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
This is a good idea, although rotate may be seldom enough used not to warrant its own (possibly overloadable) operator. std.intrinsic might be a better place for rotate. On the other hand, rotate is a single ASM instruction, at least on x86. In a close to the metal language, there needs to be a straightforward, efficient way to access it.
Dec 06 2009
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Sun, Dec 06, 2009 at 05:36:49PM +0000, dsimcha wrote:
 In a close to the metal language, there needs to be a straightforward,
efficient
 way to access it.
You could always do what I did in my D SHA implementations: uint something = whatever; asm { rol something, 5; } something += stuff; We have inline asm, so I say just go ahead and use it. Though, if you did want a D function for it (SafeD could use it then I guess), std.intrinsic is where I'd expect it to be. -- Adam D. Ruppe http://arsdnet.net
Dec 06 2009
parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-12-06 13:07:29 -0500, "Adam D. Ruppe" <destructionator gmail.com> said:

 On Sun, Dec 06, 2009 at 05:36:49PM +0000, dsimcha wrote:
 In a close to the metal language, there needs to be a straightforward, 
 efficient
 way to access it.
You could always do what I did in my D SHA implementations: uint something = whatever; asm { rol something, 5; } something += stuff; We have inline asm, so I say just go ahead and use it.
The problem with asm is portability. You can't go very far from x86 with the above code, and if you do you end up with static ifs everywhere, adding a readability problem. So an intrinsic or a built-in operator is much better. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 06 2009
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
dsimcha:
 This is a good idea, although rotate may be seldom enough used not to warrant
its
 own (possibly overloadable) operator.
Overloadable rotate operators can be used to rotate items inside an user-defined array, in my dlibs I have the templated functions rotateLeft and rotateRight, and I have used them once in a while.
 std.intrinsic might be a better place for rotate.<
In std.intrinsic I'd like to see ways to read and use the carry bit, from D. Bye, bearophile
Dec 06 2009
parent Ary Borenszweig <ary esperanto.org.ar> writes:
bearophile wrote:
 dsimcha:
 This is a good idea, although rotate may be seldom enough used not to warrant
its
 own (possibly overloadable) operator.
Overloadable rotate operators can be used to rotate items inside an user-defined array, in my dlibs I have the templated functions rotateLeft and rotateRight, and I have used them once in a while.
 std.intrinsic might be a better place for rotate.<
In std.intrinsic I'd like to see ways to read and use the carry bit, from D. Bye, bearophile
Write an enhancement request.
Dec 06 2009
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-12-06 12:36:49 -0500, dsimcha <dsimcha yahoo.com> said:

 == Quote from bearophile (bearophileHUGS lycos.com)'s article
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
This is a good idea, although rotate may be seldom enough used not to warrant its own (possibly overloadable) operator. std.intrinsic might be a better place for rotate. On the other hand, rotate is a single ASM instruction, at least on x86. In a close to the metal language, there needs to be a straightforward, efficient way to access it.
The first time I searched for a way to rotate bits, I searched for an operator and didn't find one (it was in C++ I think). So I wrote my own function; it wasn't worth the time searching further. I support <<< and >>> for rotate left and right, as an operator is the most obvious place to look for such a basic operation. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Dec 06 2009
prev sibling parent reply Don <nospam nospam.com> writes:
dsimcha wrote:
 == Quote from bearophile (bearophileHUGS lycos.com)'s article
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
This is a good idea, although rotate may be seldom enough used not to warrant its own (possibly overloadable) operator. std.intrinsic might be a better place for rotate. On the other hand, rotate is a single ASM instruction, at least on x86. In a close to the metal language, there needs to be a straightforward, efficient way to access it.
I think DMD should just do what gcc does: recognize that (x << 32-n | x>>n) is ror n (x << n | x>> 32-n) is rol n where x is int. Ugly, but doesn't require an intrinsic.
Dec 06 2009
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 03:41, Don wrote:
 dsimcha wrote:
 == Quote from bearophile (bearophileHUGS lycos.com)'s article
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
This is a good idea, although rotate may be seldom enough used not to warrant its own (possibly overloadable) operator. std.intrinsic might be a better place for rotate. On the other hand, rotate is a single ASM instruction, at least on x86. In a close to the metal language, there needs to be a straightforward, efficient way to access it.
I think DMD should just do what gcc does: recognize that (x << 32-n | x>>n) is ror n (x << n | x>> 32-n) is rol n where x is int. Ugly, but doesn't require an intrinsic.
It's still better to provide a std.???.rol(T)(T x) and ror because that (least) ugly code only works if you already know x is a uint. That ror code won't work if x is signed (int: cast into uint first) or is 64-bit (ulong: replace 32 with (8*x.sizeof)).
Dec 06 2009
parent Don <nospam nospam.com> writes:
KennyTM~ wrote:
 On Dec 7, 09 03:41, Don wrote:
 dsimcha wrote:
 == Quote from bearophile (bearophileHUGS lycos.com)'s article
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
This is a good idea, although rotate may be seldom enough used not to warrant its own (possibly overloadable) operator. std.intrinsic might be a better place for rotate. On the other hand, rotate is a single ASM instruction, at least on x86. In a close to the metal language, there needs to be a straightforward, efficient way to access it.
I think DMD should just do what gcc does: recognize that (x << 32-n | x>>n) is ror n (x << n | x>> 32-n) is rol n where x is int. Ugly, but doesn't require an intrinsic.
It's still better to provide a std.???.rol(T)(T x) and ror because that (least) ugly code only works if you already know x is a uint. That ror code won't work if x is signed (int: cast into uint first) or is 64-bit (ulong: replace 32 with (8*x.sizeof)).
That's why I said 'where x is uint'. I was trying to keep the example simple. There is no way anyone should EVER be doing a rotation on a signed type -- that's insane.
Dec 06 2009
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:

 I think DMD should just do what gcc does: recognize that
 (x << 32-n | x>>n)  is ror n
 (x << n | x>> 32-n) is rol n
 where x is int. Ugly, but doesn't require an intrinsic.
Thanks, but no thanks, it's too much ugly and it gets even more ugly if you need to use that with ulongs or ushorts, etc. It seems Walter doesn't want to remove the unsigned shift, so for the rotations it's much better to add a rol/ror to std.intrinsic (plus something to read the carry bit, etc). Bye, bearophile
Dec 06 2009
parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 Don:
 
 I think DMD should just do what gcc does: recognize that
 (x << 32-n | x>>n)  is ror n
 (x << n | x>> 32-n) is rol n
 where x is int. Ugly, but doesn't require an intrinsic.
Thanks, but no thanks, it's too much ugly and it gets even more ugly if you need to use that with ulongs or ushorts, etc. It seems Walter doesn't want to remove the unsigned shift, so for the rotations it's much better to add a rol/ror to std.intrinsic (plus something to read the carry bit, etc). Bye, bearophile
The problem is, std.intrinsic is scarcely more portable than inline asm. It doesn't even work on LDC! You then get problems with user defined types that want to have a rotate. BTW, if the above intrinsic existed, you would just define: T ror(T)(T x, uint n) { return (x << ((T.sizeof*8)-n) | x>>n); }
Dec 06 2009
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 05:02, Don wrote:
 bearophile wrote:
 Don:

 I think DMD should just do what gcc does: recognize that
 (x << 32-n | x>>n) is ror n
 (x << n | x>> 32-n) is rol n
 where x is int. Ugly, but doesn't require an intrinsic.
Thanks, but no thanks, it's too much ugly and it gets even more ugly if you need to use that with ulongs or ushorts, etc. It seems Walter doesn't want to remove the unsigned shift, so for the rotations it's much better to add a rol/ror to std.intrinsic (plus something to read the carry bit, etc). Bye, bearophile
The problem is, std.intrinsic is scarcely more portable than inline asm. It doesn't even work on LDC! You then get problems with user defined types that want to have a rotate. BTW, if the above intrinsic existed, you would just define: T ror(T)(T x, uint n) { return (x << ((T.sizeof*8)-n) | x>>n); }
Shouldn't that be a problem of ldc, the implementation of std.intrinsic, or both? The interface of std.intrinsic is perfectly fine.
Dec 06 2009
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Don:
 It doesn't even work on LDC!
Are you sure? I think they work with LDC.
 You then get problems with user defined types that want to have a rotate.
Having two built-in operators to perform rotations can solve that, but I agree it may be overkill.
 BTW, if the above intrinsic existed, you would just define:
I see. Bye, bearophile
Dec 06 2009
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 01:24, bearophile wrote:
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
No, it will _silently_ break code that uses >>> as unsigned right shift.
Dec 06 2009
parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from KennyTM~ (kennytm gmail.com)'s article
 On Dec 7, 09 01:24, bearophile wrote:
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
No, it will _silently_ break code that uses >>> as unsigned right shift.
Well, we could get around this by making >>> an error for a few releases, and then only after everyone's removed their >>>s that mean unsigned shift, we could drop in the rotate semantics.
Dec 06 2009
next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Sun, 06 Dec 2009 23:00:42 +0300, dsimcha <dsimcha yahoo.com> wrote:

 == Quote from KennyTM~ (kennytm gmail.com)'s article
 On Dec 7, 09 01:24, bearophile wrote:
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
No, it will _silently_ break code that uses >>> as unsigned right shift.
Well, we could get around this by making >>> an error for a few releases, and then only after everyone's removed their >>>s that mean unsigned shift, we could drop in the rotate semantics.
Why not just make an instrinsic function for that? Is it *really* used that often to deserve a unique identifier?
Dec 06 2009
prev sibling next sibling parent Chad J <chadjoan __spam.is.bad__gmail.com> writes:
dsimcha wrote:
 == Quote from KennyTM~ (kennytm gmail.com)'s article
 No, it will _silently_ break code that uses >>> as unsigned right shift.
Well, we could get around this by making >>> an error for a few releases, and then only after everyone's removed their >>>s that mean unsigned shift, we could drop in the rotate semantics.
Only works so well. This would still remain a problem for porting other languages to D. Java code would silently break as it is ported, for example. If you're porting you need to know these things anyways, but it doesn't help. It doesn't seem justified to add such a problem just to get convenient notation for bit rotation. FWIW, I'd be perfectly happy with >>> just being removed.
Dec 06 2009
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
dsimcha wrote:
 == Quote from KennyTM~ (kennytm gmail.com)'s article
 No, it will _silently_ break code that uses >>> as unsigned right shift.
Well, we could get around this by making >>> an error for a few releases, and then only after everyone's removed their >>>s that mean unsigned shift, we could drop in the rotate semantics.
It'll still silently break code moving from D1 to D2.
Dec 06 2009
parent reply Jerry Quinn <jlquinn optonline.net> writes:
Walter Bright Wrote:

 dsimcha wrote:
 == Quote from KennyTM~ (kennytm gmail.com)'s article
 No, it will _silently_ break code that uses >>> as unsigned right shift.
Well, we could get around this by making >>> an error for a few releases, and then only after everyone's removed their >>>s that mean unsigned shift, we could drop in the rotate semantics.
It'll still silently break code moving from D1 to D2.
Well, I could see the value of poviding a rotate operator. Since >>> is tainted, what about >> and << for integral rotation? Jerry
Dec 06 2009
next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Dec 7, 09 09:11, Jerry Quinn wrote:
 Walter Bright Wrote:

 dsimcha wrote:
 == Quote from KennyTM~ (kennytm gmail.com)'s article
 No, it will _silently_ break code that uses>>>  as unsigned right shift.
Well, we could get around this by making>>> an error for a few releases, and then only after everyone's removed their>>>s that mean unsigned shift, we could drop in the rotate semantics.
It'll still silently break code moving from D1 to D2.
Well, I could see the value of poviding a rotate operator. Since>>> is tainted, what about>> and<< for integral rotation? Jerry
Why these must be implemented through additional operators?
Dec 06 2009
prev sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 07 Dec 2009 02:11:16 +0100, Jerry Quinn <jlquinn optonline.net>  
wrote:

 Walter Bright Wrote:

 dsimcha wrote:
 == Quote from KennyTM~ (kennytm gmail.com)'s article
 No, it will _silently_ break code that uses >>> as unsigned right  
shift.
 Well, we could get around this by making >>> an error for a few  
releases, and then
 only after everyone's removed their >>>s that mean unsigned shift, we  
could drop
 in the rotate semantics.
It'll still silently break code moving from D1 to D2.
Well, I could see the value of poviding a rotate operator. Since >>> is tainted, what about >> and << for integral rotation? Jerry
I was thinking <<> and <>>. They represent the fact that some bits end up on the wrong side. Still, I don't think there're enough use cases for an operator. -- Simen
Dec 07 2009
parent Jerry Quinn <jlquinn optonline.net> writes:
Simen kjaeraas Wrote:

 On Mon, 07 Dec 2009 02:11:16 +0100, Jerry Quinn <jlquinn optonline.net>  
 wrote:
 Well, I could see the value of poviding a rotate operator.

 Since >>> is tainted, what about >>  and <<  for integral rotation?
I was thinking <<> and <>>. They represent the fact that some bits end up on the wrong side. Still, I don't think there're enough use cases for an operator.
I'd argue against <<> and <>> since they'd be very easy to misread and mistype. I can believe that an operator isn't necessary, but there should definitely be a standard way for folks to end up with single-asm instructions for rotation without resorting to ugliness. Consider PowerPC that has a whole collection of powerful rotation instructions.
Dec 07 2009
prev sibling next sibling parent Lionello Lunesu <lio lunesu.remove.com> writes:
On 7-12-2009 1:24, bearophile wrote:
 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Bye, bearophile
I thought that idea was so crazy that I just went ahead and post it myself... Good idea though ;) L.
Dec 06 2009
prev sibling parent retard <re tard.com.invalid> writes:
Sun, 06 Dec 2009 12:24:33 -0500, bearophile wrote:

 Andrei Alexandrescu:
 Should we yank operator>>>?
We can change it purpose and add the other one: <<< rotate left
 rotate right
Or some other user cases a >>> 1 // count the number of leading 1s a <<< 0 // count the number of trailing zeros Those are also single instructions on some architectures. :)
Dec 07 2009
prev sibling next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 D has operator >>> which means "unsigned shift to the right", inherited
 from Java. But it doesn't need it because D has unsigned types, which
 can be used to effect unsigned shift. (Java, lacking unsigned types, had
 no other way around but to define a new operator.)
 Should we yank operator>>>?
 Andrei
I've never used >>> before, so I'm not 100% sure I understand what it's supposed to do. However, I wrote a test program to see if it does what I think, and if my understanding is correct, it's not even properly implemented. The fact that noone's noticed until now is a pretty clear indication that noone uses >>> . Test program: import std.stdio; void main() { int i = 0b10000000_00000000_00000000_00000010; int iSigned = i >> 2; writefln(" int >>: %.32b", iSigned); int iUnsigned = i >>> 2; writefln(" int >>>: %.32b", iUnsigned); uint u = cast(uint) i; uint uSigned = u >> 2; writefln(" uint >>: %.32b", uSigned); uint uUnsigned = u >>> 2; writefln("uint >>>: %.32b", uUnsigned); } Output (DMD 2.037): int >>: 11100000000000000000000000000000 int >>>: 11100000000000000000000000000000 uint >>: 00100000000000000000000000000000 uint >>>: 00100000000000000000000000000000
Dec 06 2009
parent Don <nospam nospam.com> writes:
dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 D has operator >>> which means "unsigned shift to the right", inherited
 from Java. But it doesn't need it because D has unsigned types, which
 can be used to effect unsigned shift. (Java, lacking unsigned types, had
 no other way around but to define a new operator.)
 Should we yank operator>>>?
 Andrei
I've never used >>> before, so I'm not 100% sure I understand what it's supposed to do. However, I wrote a test program to see if it does what I think, and if my understanding is correct, it's not even properly implemented. The fact that noone's noticed until now is a pretty clear indication that noone uses >>> .
Not so. That must be a regression caused by bugzilla 3115. Ouch.
Dec 06 2009
prev sibling next sibling parent reply Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 D has operator >>> which means "unsigned shift to the right", inherited 
 from Java. But it doesn't need it because D has unsigned types, which 
 can be used to effect unsigned shift. (Java, lacking unsigned types, had 
 no other way around but to define a new operator.)
 
 Should we yank operator>>>?
 
 
 Andrei
Yes. It's an operation that doesn't make much sense -- it operates on raw bits, not on integers. It's tied to a twos-complement representation, and not to mathematics. If you ever try to implement >>> for bigints, you find out how wierd it is. I guess in the Java case, x>>>1 is cast(int)((cast(uint)x)>>1) and there's no other way of doing it in a language which had no unsigned types. It had some merit before D had templates. Now, I don't think it has much use.
Dec 06 2009
parent Walter Bright <newshound1 digitalmars.com> writes:
Don wrote:
 It's tied to a twos-complement 
 representation, and not to mathematics.
That's true, and D explicitly is tied to twos-complement integers.
Dec 06 2009
prev sibling next sibling parent Walter Bright <newshound1 digitalmars.com> writes:
Andrei Alexandrescu wrote:
 D has operator >>> which means "unsigned shift to the right", inherited 
 from Java. But it doesn't need it because D has unsigned types, which 
 can be used to effect unsigned shift. (Java, lacking unsigned types, had 
 no other way around but to define a new operator.)
It's there because in C/C++ one often winds up writing: (unsigned)x >> i; to ensure that one gets an unsigned right shift. The problem is that the cast can have many other side effects if x is not of type int. For example, if x is a struct with an overloaded cast operator. Or if x is a long and you just lost half your value.
 Should we yank operator>>>?
No.
Dec 06 2009
prev sibling parent Lionello Lunesu <lio lunesu.remove.com> writes:
On 7-12-2009 0:11, Andrei Alexandrescu wrote:
 D has operator >>> which means "unsigned shift to the right", inherited
 from Java. But it doesn't need it because D has unsigned types, which
 can be used to effect unsigned shift. (Java, lacking unsigned types, had
 no other way around but to define a new operator.)
 
 Should we yank operator>>>?
 
 
 Andrei
Ah!! Keep it, but let it mean "rotate right" and introduce <<< to mean "rotate left"! There's currently no rotate operator and the only way to do rotate is either write unportable inline asm or do "(x<<s) | (x>>(sizeof(x)*8-s))" OK, so people coming from Java *will* be surprised :) L.
Dec 06 2009