Reputation: 67
I've been trying to get this to work for several days now, I've read a thousand guides and people's questions, but still, I can't find a way to do it properly.
What I want to do is to rotate the bits to the left, here's an example.
Original number = 10000001 = 129
What I need = 00000011 = 3
I have to rotate the bits to left a certain amount of times (it depends on what the user types), here's what I did:
byte b = (byte)129;
byte result = (byte)((byte)b << 1);
Console.WriteLine(result);
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
The issue with this it that it causes an error (OverflowException) when I try to use the (<<) operator with that number (note that if I put a number which first bit is a 0; example: 3 = 00000011; it works as intended and it returns a 6 as a result.
The problem is, if the first bit is a 1, it gives me the (OverflowException) error. I know this isn't rotating, its just a shifting, the first bit goes away and on the end of the byte a 0 pops up, and I can then change it with an OR 000000001 operation to make it a 1 (if the first bit was a 1, if it was a 0 I just leave it there).
Upvotes: 6
Views: 1704
Reputation: 1
please try this function - rotates in both directions (left and right rotation of an 8 bit value) [I didn't tested that function!]
// just for 8Bit values (byte)
byte rot(byte value, int rotation)
{
rotation %= 8;
int result;
if(rotation < 0)
{
result = value << (8 + rotation);
}
else
{
result = value << rotation;
}
byte[] resultBytes = BitConverter.GetBytes(result);
result = resultBytes[0] | resultBytes[1];
return (byte)result;
}
short rot(short value, int rotation) { ... }
int rot(int value, int rotation) { ... }
Upvotes: 0
Reputation: 67
Thanks for your answers!
Shortly after i made this post i came up with an idea to solve this problem, let me show you (Before you ask, it works!):
byte b = (byte)129;
b = (byte)((byte)b & 127);
byte result = (byte)((byte)b << 1);
result = (byte)((byte)result | 1);
Console.WriteLine(result);
What this does is, removes the first bit (in case if it is a 1) it shifts to the left that zero (doesnt generate overflow) and once the shift is over, it changes that 0 back to 1. If that first bit was a 0, it will just move that zero (note that this is just a piece of the whole code, and as it is partially written in spanish (the comments and variables) i doubt you will understand most of it, so i decided to take out the problematic part to show it to you guys!
I will still try the things you told me and see how it goes, again, thanks a lot for your answers!
Upvotes: 0
Reputation: 1502806
You're getting an overflow exception because you're operating in a checked context, apparently.
You can get around that by putting the code in an unchecked context - or just by making sure you don't perform the cast back to byte
on a value that can be more than 255. For example:
int shifted = b << rotateLeftBits;
int highBits = shifted & 0xff;
int lowBits = shifted >> 8; // Previously high bits, rotated
byte result = (byte) (highBits | lowBits);
This will work for rotate sizes of up to 8. For greater sizes, just use rotateLeftBits % 8
(and normalize to a non-negative number if you might sometimes want to rotate right).
Upvotes: 8
Reputation: 882206
<<
is a shift operator, not a rotate one.
If you want to rotate, you can use (with suitable casting):
b = (b >> 7) | ((b & 0x7f) << 1);
The first part of that gets the leftmost bit down to the rightmost, the second part shifts all the other left.
The or
-ing them with |
combines the two.
Upvotes: 4