Rotate.NET

One of the remarkable missing CPU instructions from the .NET BCL is bitwise rotation. The shift operators are there: <<, >>. The following implementation fills out the blanks (based on RCA Lab's RC5 reference implementation).

static class Spinner  
{
    const byte LongLong = 64;
    const byte Long = 32;
    const byte Word = 16;
    const byte Byte = 8;
    public static UInt64 RotateLeft(this UInt64 x, byte leftShifts) {
        return ((x) << (leftShifts & (LongLong - 1))) 
            | ((x) >> (LongLong - (leftShifts & (LongLong - 1))));
    }
    public static UInt64 RotateRight(this UInt64 x, byte rightShifts) {
        return ((x) >> (rightShifts & (LongLong - 1))) 
            | ((x) << (LongLong - (rightShifts & (LongLong - 1))));
    }
    public static uint RotateLeft(this uint x, byte leftShifts) {
        return ((x) << (leftShifts & (Long - 1))) 
            | ((x) >> (Long - (leftShifts & (Long - 1))));
    }
    public static uint RotateRight(this uint x, byte rightShifts) {
        return ((x) >> (rightShifts & (Long - 1))) 
            | ((x) << (Long - (rightShifts & (Long - 1))));
    }
    public static ushort RotateLeft(this ushort x, byte leftShifts) {
        return unchecked((ushort)(((x) << (leftShifts & (Word - 1))) 
            | ((x) >> (Word - (leftShifts & (Word - 1))))));
    }
    public static ushort RotateRight(this ushort x, byte rightShifts) {
        return unchecked((ushort)(((x) >> (rightShifts & (Word - 1))) 
            | ((x) << (Word - (rightShifts & (Word - 1))))));
    }
    public static byte RotateLeft(this byte x, byte leftShifts) {
        return unchecked((byte)(((x) << (leftShifts & (Byte - 1))) 
            | ((x) >> (Byte - (leftShifts & (Byte - 1))))));
    }
    public static byte RotateRight(this byte x, byte rightShifts) {
        return unchecked((byte)(((x) >> (rightShifts & (Byte - 1))) 
            | ((x) << (Byte - (rightShifts & (Byte - 1))))));
    }       
}
Google
m@kli.dk @klinkby RSS feed  GitHub