3

In C++ I have code like this.

    static UInt32 rol(UInt32 value, UInt32 bits)
    {
        bits &= 31;
        return ((value << bits) | (value >> (32 - bits)));
    }

    static UInt32 ror(UInt32 value, UInt32 bits)
    {
        bits &= 31;
        return ((value >> bits) | (value << (32 - bits)));
    }

how would it look in C#? I think the same exact way.. only problem

Error 2 Operator '>>' cannot be applied to operands of type 'uint' and 'uint'
Error 3 Operator '>>' cannot be applied to operands of type 'uint' and 'uint'
Error 1 Operator '<<' cannot be applied to operands of type 'uint' and 'uint'
Error 4 Operator '<<' cannot be applied to operands of type 'uint' and 'uint'

SSpoke
  • 5,656
  • 10
  • 72
  • 124
  • For the record: best-practices for expressing rotates in a compiler-friendly way, avoiding C undefined behaviour: http://stackoverflow.com/questions/776508/circular-shift-rotate-operations-in-c. When `bits == 0`, this code will shift the 32b `value` by 32bits. Hopefully that's legal in C#. – Peter Cordes Aug 17 '15 at 17:40

4 Answers4

3

You should use int type for the right side variable in shift operators.

oxilumin
  • 4,775
  • 2
  • 18
  • 25
  • wouldn't that mess with `bits &= 31;` logic though? must I create another variable after that? if I just change `UInt32 bits` to `int bits` fixes everything but will that `bits AND 31` logic ever mess up? – SSpoke Sep 02 '11 at 21:22
  • You can replace `bits &= 31` by `bits %= 32`. – oxilumin Sep 02 '11 at 21:27
  • Why the use of Contract? is that to surpass exceptions? I cannot find that library in my .NET framework. – SSpoke Sep 02 '11 at 21:29
  • It's just a way to write `if then throw` expression in one string, plus - you have static checking with code contracts library. You can learn about it at [microsoft site](http://research.microsoft.com/en-us/projects/contracts/) – oxilumin Sep 02 '11 at 21:30
  • @SSpoke: no, the result of `var &= 31;` isn't affected by signedness. Signedness changes the meaning of the MSB only. – Ben Voigt Sep 02 '11 at 21:51
1

You will have to cast the right side of the bitshift operator to int. If you cast like (int)(32 - bits), it should not affect your intended purpose. The right side is just expecting an int, probably because it's simpler that way and highly unlikely you'll ever want to shift more than 2 billion bits.

Michael Yoon
  • 1,606
  • 11
  • 9
  • ya screw it I picked your solution.. easier fix.. `return ((value << (int)bits) | (value >> (int)(32 - bits)));` and `return ((value >> (int)bits) | (value << (int)(32 - bits)));` – SSpoke Sep 02 '11 at 21:32
1

The right operand must be always type int.

 int x << int bits
 uint x << int bits
 long x << int bits
 ulong x << int bits
Senthil
  • 106
  • 1
  • 9
0

Add some parentheses and it works:

byte[] bytes = { 1, 2, 4, 8 };
UInt32 crc32 = ((UInt32)msg.Data[3] << 24) +
    ((UInt32)msg.Data[2] << 16) +
    ((UInt32)msg.Data[1] << 8) +
    msg.Data[0];
Marek Pio
  • 49
  • 8