How to Perform a Circular Bit Shift in C#

Is there a way to perform a circular bit shift in C#?

If you know the size of type, you could do something like:

uint i = 17;
uint j = i << 1 | i >> 31;

... which would perform a circular shift of a 32 bit value.

As a generalization to circular shift left n bits, on a b bit variable:

/*some unsigned numeric type*/ input = 17;
var result = input << n | input >> (b - n);



@The comment, it appears that C# does treat the high bit of signed values differently. I found some info on this here. I also changed the example to use a uint.

Right Circular Shift C#

Assuming 0 <= shift, try

private string leftRotateShift(string key, int shift)
{
shift %= key.Length;
return key.Substring(shift) + key.Substring(0, shift);
}

private string rightRotateShift(string key, int shift)
{
shift %= key.Length;
return key.Substring(key.Length - shift) + key.Substring(0, key.Length - shift);
}

C# bitwise rotate left and rotate right

Is this what you are trying to do?

Jon Skeet answered this in another site

Basically what you want is

(for left)

(original << bits) | (original >> (32 - bits))

or

(for right)

(original >> bits) | (original << (32 - bits))

Also, as Mehrdad has already suggested, this only works for uint, which is the example that Jon gives as well.

Circular shift Int32 digits using C#

Because I just can't resist a 'has to have an arithmetic approach' challenge :D , fiddled around with the following:

    static uint RotateShift(uint value, int shift)
{
int len = (int)Math.Log10(value) + 1;
shift %= len;
if (shift < 0) shift += len;
uint pow = (uint)Math.Pow(10, shift);
return (value % pow) * (uint)Math.Pow(10, len - shift) + value / pow;
}

edit Also some test results

foreach(var val in new uint[]{123456789, 12345678})
foreach (var shift in new[] { 3, -3, 1, -1, 11, -11, 18 })
{
Console.WriteLine("Value {0} Shift {1} -> {2}", val, shift, RotateShift(val, shift));
}

Value 123456789 Shift 3 -> 789123456
Value 123456789 Shift -3 -> 456789123
Value 123456789 Shift 1 -> 912345678
Value 123456789 Shift -1 -> 234567891
Value 123456789 Shift 11 -> 891234567
Value 123456789 Shift -11 -> 345678912
Value 123456789 Shift 18 -> 123456789
Value 12345678 Shift 3 -> 67812345
Value 12345678 Shift -3 -> 45678123
Value 12345678 Shift 1 -> 81234567
Value 12345678 Shift -1 -> 23456781
Value 12345678 Shift 11 -> 67812345
Value 12345678 Shift -11 -> 45678123
Value 12345678 Shift 18 -> 78123456

Is there any C# bitwise shift operator that moves the overflown bits to the other tip of the variable?

That would be a called a bit rotate and C# does not have such an operator.

Here's an interesting post:
Is there a way to perform a circular bit shift in C#?

Note that your int32integer should be of type uint (unsigned int).

I believe bit rotate is an instructions in the Intel instruction set but as far as I know the CLR does not have bit rotate instructions.

Bitwise - shift around

Thanks for the links. It looks like I am doing it quite well anyway. Here is my javascript function:

// Returns the new number
// This assumes the lowest bit of the number is on the right
// So going left puts the high number bits at the bottom on the right
// So going right puts the lowest bits to the left high number bits
// 'value' is the number you are doing it to
// 'shift' is how many bits you are shifting Minus is left, Plus is right
// 'maxbits' is the max bits in the number
function RotateLeftRight (value, shift, maxbits) {
var doLeft;
var ret, rightShift, leftShift, mask;

if (maxbits <= 0) return 0; // Nothing to do
ret = value & (Math.pow(2, maxbits) - 1); // Mask out the value so it has the correct bits to start with
doLeft = shift < 0 ? true : false;
if(doLeft) shift = -shift;
shift %= maxbits;
if(shift === 0) return ret;
if (doLeft) {
rightShift = maxbits - shift;
leftShift = shift;
mask = Math.pow(2, maxbits - shift) - 1;
} else {
rightShift = shift;
leftShift = maxbits - shift;
mask = Math.pow(2, shift) - 1;
}
return ((ret >> rightShift) | ((ret & mask) << leftShift));
};

I will mark this as answer, unless anyone would like to input any more.

Is there a function to do circular bitshift for a byte array in C#?

This is not as simple as you'd think. Here's a quick version before this thread gets closed:

public static byte[] ROL_ByteArray(byte[] arr, int nShift)
{
//Performs bitwise circular shift of 'arr' by 'nShift' bits to the left
//RETURN:
// = Result
byte[] resArr = new byte[arr.Length];

if(arr.Length > 0)
{
int nByteShift = nShift / (sizeof(byte) * 8); //Adjusted after @dasblinkenlight's correction
int nBitShift = nShift % (sizeof(byte) * 8);

if (nByteShift >= arr.Length)
nByteShift %= arr.Length;

int s = arr.Length - 1;
int d = s - nByteShift;

for (int nCnt = 0; nCnt < arr.Length; nCnt++, d--, s--)
{
while (d < 0)
d += arr.Length;
while (s < 0)
s += arr.Length;

byte byteS = arr[s];

resArr[d] |= (byte)(byteS << nBitShift);
resArr[d > 0 ? d - 1 : resArr.Length - 1] |= (byte)(byteS >> (sizeof(byte) * 8 - nBitShift));

}
}

return resArr;
}

and here's a test:

byte[] arr = new byte[] {
Convert.ToByte("11001110", 2),
Convert.ToByte("01000100", 2),
Convert.ToByte("10100001", 2),
};

byte[] arr2 = Auth.ROL_ByteArray(arr, 1);

string sss = "";
for (int i = 0; i < arr2.Length; i++)
sss += Convert.ToString(arr2[i], 2) + ", ";

Debug.WriteLine(sss);

C# binary shift rotates automatically

It doesn't "rotate" as such; simply - only some of the bits of the operand are considered. Basically, 1 << 32 is identical to 1 << 0.

From MSDN

If the first operand is an int or uint (32-bit quantity), the shift count is given by the low-order five bits of the second operand. That is, the actual shift count is 0 to 31 bits.

If the first operand is a long or ulong (64-bit quantity), the shift count is given by the low-order six bits of the second operand. That is, the actual shift count is 0 to 63 bits.



Related Topics



Leave a reply



Submit