digitalmars.D - yank '>>>'?
- Andrei Alexandrescu (6/6) Dec 06 2009 D has operator >>> which means "unsigned shift to the right", inherited
- Ellery Newcomer (12/18) Dec 06 2009 taking the opportunity to review what the difference is between >> and >...
- bearophile (5/7) Dec 06 2009 We can change it purpose and add the other one:
- dsimcha (6/13) Dec 06 2009 This is a good idea, although rotate may be seldom enough used not to wa...
- Adam D. Ruppe (11/13) Dec 06 2009 You could always do what I did in my D SHA implementations:
- Michel Fortin (9/23) Dec 06 2009 The problem with asm is portability. You can't go very far from x86
- bearophile (5/8) Dec 06 2009 In std.intrinsic I'd like to see ways to read and use the carry bit, fro...
- Ary Borenszweig (2/15) Dec 06 2009 Write an enhancement request.
- Michel Fortin (10/28) Dec 06 2009 The first time I searched for a way to rotate bits, I searched for an
- Don (5/19) Dec 06 2009 I think DMD should just do what gcc does: recognize that
- KennyTM~ (5/28) Dec 06 2009 It's still better to provide a std.???.rol(T)(T x) and ror because that
- Don (5/37) Dec 06 2009 That's why I said 'where x is uint'. I was trying to keep the example
- bearophile (4/8) Dec 06 2009 Thanks, but no thanks, it's too much ugly and it gets even more ugly if ...
- Don (9/20) Dec 06 2009 The problem is, std.intrinsic is scarcely more portable than inline asm.
- KennyTM~ (3/27) Dec 06 2009 Shouldn't that be a problem of ldc, the implementation of std.intrinsic,...
- bearophile (6/9) Dec 06 2009 Having two built-in operators to perform rotations can solve that, but I...
- KennyTM~ (2/9) Dec 06 2009 No, it will _silently_ break code that uses >>> as unsigned right shift.
- dsimcha (4/15) Dec 06 2009 Well, we could get around this by making >>> an error for a few releases...
- Denis Koroskin (3/20) Dec 06 2009 Why not just make an instrinsic function for that? Is it *really* used
- Chad J (8/14) Dec 06 2009 Only works so well.
- Walter Bright (2/8) Dec 06 2009 It'll still silently break code moving from D1 to D2.
- Jerry Quinn (4/13) Dec 06 2009 Well, I could see the value of poviding a rotate operator.
- KennyTM~ (2/15) Dec 06 2009 Why these must be implemented through additional operators?
- Simen kjaeraas (7/23) Dec 07 2009 I was thinking <<> and <>>. They represent the fact that some bits end u...
- Jerry Quinn (2/11) Dec 07 2009 I'd argue against <<> and <>> since they'd be very easy to misread and m...
- Lionello Lunesu (5/14) Dec 06 2009 I thought that idea was so crazy that I just went ahead and post it
- retard (5/10) Dec 07 2009 Or some other user cases
- dsimcha (24/30) Dec 06 2009 I've never used >>> before, so I'm not 100% sure I understand what it's ...
- Don (2/14) Dec 06 2009 Not so. That must be a regression caused by bugzilla 3115. Ouch.
- Don (10/19) Dec 06 2009 Yes. It's an operation that doesn't make much sense -- it operates on
- Walter Bright (2/4) Dec 06 2009 That's true, and D explicitly is tied to twos-complement integers.
- Walter Bright (8/13) Dec 06 2009 It's there because in C/C++ one often winds up writing:
- Lionello Lunesu (7/16) Dec 06 2009 Ah!! Keep it, but let it mean "rotate right" and introduce <<< to mean
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
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>>>? Andreitaking 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
Andrei Alexandrescu:Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
== Quote from bearophile (bearophileHUGS lycos.com)'s articleAndrei Alexandrescu: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.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
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
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: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/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.
Dec 06 2009
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
bearophile wrote:dsimcha:Write an enhancement request.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
On 2009-12-06 12:36:49 -0500, dsimcha <dsimcha yahoo.com> said:== Quote from bearophile (bearophileHUGS lycos.com)'s articleThe 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/Andrei Alexandrescu: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.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
dsimcha wrote:== Quote from bearophile (bearophileHUGS lycos.com)'s articleI 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.Andrei Alexandrescu: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.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
On Dec 7, 09 03:41, Don wrote:dsimcha wrote: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)).== Quote from bearophile (bearophileHUGS lycos.com)'s articleI 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.Andrei Alexandrescu: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.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
KennyTM~ wrote:On Dec 7, 09 03:41, Don wrote: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.dsimcha wrote: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)).== Quote from bearophile (bearophileHUGS lycos.com)'s articleI 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.Andrei Alexandrescu: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.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
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
bearophile wrote:Don: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); }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
On Dec 7, 09 05:02, Don wrote:bearophile wrote:Shouldn't that be a problem of ldc, the implementation of std.intrinsic, or both? The interface of std.intrinsic is perfectly fine.Don: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); }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
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
On Dec 7, 09 01:24, bearophile wrote:Andrei Alexandrescu:No, it will _silently_ break code that uses >>> as unsigned right shift.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
== Quote from KennyTM~ (kennytm gmail.com)'s articleOn Dec 7, 09 01:24, bearophile wrote: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.Andrei Alexandrescu:No, it will _silently_ break code that uses >>> as unsigned right shift.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
On Sun, 06 Dec 2009 23:00:42 +0300, dsimcha <dsimcha yahoo.com> wrote:== Quote from KennyTM~ (kennytm gmail.com)'s articleWhy not just make an instrinsic function for that? Is it *really* used that often to deserve a unique identifier?On Dec 7, 09 01:24, bearophile wrote: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.Andrei Alexandrescu:No, it will _silently_ break code that uses >>> as unsigned right shift.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
dsimcha wrote:== Quote from KennyTM~ (kennytm gmail.com)'s articleOnly 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.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
dsimcha wrote:== Quote from KennyTM~ (kennytm gmail.com)'s articleIt'll still silently break code moving from D1 to D2.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
Walter Bright Wrote:dsimcha wrote:Well, I could see the value of poviding a rotate operator. Since >>> is tainted, what about >> and << for integral rotation? Jerry== Quote from KennyTM~ (kennytm gmail.com)'s articleIt'll still silently break code moving from D1 to D2.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
On Dec 7, 09 09:11, Jerry Quinn wrote:Walter Bright Wrote:Why these must be implemented through additional operators?dsimcha wrote:Well, I could see the value of poviding a rotate operator. Since>>> is tainted, what about>> and<< for integral rotation? Jerry== Quote from KennyTM~ (kennytm gmail.com)'s articleIt'll still silently break code moving from D1 to D2.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
On Mon, 07 Dec 2009 02:11:16 +0100, Jerry Quinn <jlquinn optonline.net> wrote:Walter Bright Wrote: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. -- Simendsimcha wrote:Well, I could see the value of poviding a rotate operator. Since >>> is tainted, what about >> and << for integral rotation? Jerry== Quote from KennyTM~ (kennytm gmail.com)'s articleshift.No, it will _silently_ break code that uses >>> as unsigned rightWell, we could get around this by making >>> an error for a fewreleases, and thenonly after everyone's removed their >>>s that mean unsigned shift, wecould dropin the rotate semantics.It'll still silently break code moving from D1 to D2.
Dec 07 2009
Simen kjaeraas Wrote:On Mon, 07 Dec 2009 02:11:16 +0100, Jerry Quinn <jlquinn optonline.net> wrote: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.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.
Dec 07 2009
On 7-12-2009 1:24, bearophile wrote:Andrei Alexandrescu:I thought that idea was so crazy that I just went ahead and post it myself... Good idea though ;) L.Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftBye, bearophilerotate right
Dec 06 2009
Sun, 06 Dec 2009 12:24:33 -0500, bearophile wrote:Andrei Alexandrescu: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. :)Should we yank operator>>>?We can change it purpose and add the other one: <<< rotate leftrotate right
Dec 07 2009
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleD 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>>>? AndreiI'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
dsimcha wrote:== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s articleNot so. That must be a regression caused by bugzilla 3115. Ouch.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>>>? AndreiI'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 >>> .
Dec 06 2009
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>>>? AndreiYes. 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
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
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
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>>>? AndreiAh!! 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