views:

2721

answers:

3

Hi

I am looking for C# equivalent (.Net 2) of _rotl and _rotr from c++.

Any ideas ?

Thanks,

+7  A: 

There's no built-in language feature for bit rotation in C#, but these extension methods should do the job:

public static uint RotateLeft(this uint value, int count)
{
    return (value << count) | (value >> (32 - count))
}

public static uint RotateLeft(this uint value, int count)
{
    return (value >> count) | (value << (32 - count))
}

Note: As Mehrdad points out, right-shift (>>) for signed integers is a peculiarity: it fills the MSBs with sign bit rather than 0 as it does for unsigned numbers. I've now changed the methods to take and return uint (unsigned 32-bit integer) instead - this is also in greater accordance with the C++ rotl and rotr functions. If you want to rotate integers, just case them before passing, and again cast the return value, of course.

Example usage:

int foo1 = 8.RotateRight(3); // foo1 = 1
int foo2 = int.MinValue.RotateLeft(3); // foo2 = 4

(Note that int.MinValue is 111111111111111111111111 - 32 1s in binary.)

Noldorin
That's a shift, not rotate!
Mehrdad Afshari
@Mehrdad: Yeah, just realised that as I posted. Fixed now. :)
Noldorin
I think this will fail for negative numbers. You probably want to force the values to be unsigned.
plinth
@plinth: It won't fail. The bitwise operations work exactly the same for signed and unsigned numbers, only that the number represented by signed ints can change sign during bit shifting/rotation because of the two's complement system.
Noldorin
Noldorin: Wrong. won't work due to how right shift works.
Mehrdad Afshari
@Mehrdad: So I learnt something new. :) Will edit the post to fix it.
Noldorin
Would this work? http://stackoverflow.com/questions/776508/circular-shift-operations-in-c/776555#776555
Richard Inglis
@Richard: That looks like bit magic and would probably take me a while to figure out. I'll take the poster's word that it works however. You're probably still better off just casting, as it's simple and doesn't require seperate functions for int and unit. However, that function *may* beat this one + casting in speed, though it's not something to bother about in general.
Noldorin
@Richard: It'll work. It's not magic. First line of it is unnecessary. The second line is essentially what mentioned in this post. The first line means to zero out the MSBs of the number by "and"ing the input with some number like 00000011111 (L right bits are 1, rest is zero). To get such a number you'd want to decrement one from 1000000) :) There's no reason to zero out at all since the shift will do it automatically.
Mehrdad Afshari
+7  A: 

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.

Joseph
i have tried this but it is not procducing the right result. FOR c++if original =1192314641outout of _roti(1192314641,3) = 948582538For C# Using above formula output = 948582536
Prithis
@Prithis I just ran a test on it myself and I got 948582538 in C#
Joseph
ignore me it is working. Thanks
Prithis
This works correctly **only** if `original` is `uint`. Note that Jon Skeet does it with `uint`.
Mehrdad Afshari
@Merhdad Thanks I updated answer to reflect.
Joseph
@Mehrdad Luckly I was looking for a solution with 'uint'
Prithis
+1  A: 

The naive version of shifting won't work. The reason is, right shifting signed numbers will fill the left bits with sign bit, not 0:

You can verify this fact with:

Console.WriteLine(-1 >> 1);

The correct way is:

public static int RotateLeft(this int value, int count)
{
    uint val = (uint)value;
    return (int)((val << count) | (val >> (32 - count)));
}

public static int RotateRight(this int value, int count)
{
    uint val = (uint)value;
    return (int)((value >> count) | (value << (32 - count)));
}
Mehrdad Afshari
or you could change the extension method to bring in a uint and return a uint, which is what Jon did
Joseph
@Joseph: In that case, you should do the cast manually when you call with an int.
Mehrdad Afshari
Yeah, it would make more sense for the function just to take/return uint (that's what I've done in my updated post too). Otherwise, if you actually want to rotate a uint, you'd be casting 4 times when you don't in fact need to do any!
Noldorin
@Mehrdad That's correct, but I wasn't assuming it was an int to begin with.
Joseph
Noldorin: You could create a set of extension methods for `uint` to. Anyway, it doesn't really matter much. These casts won't matter at the level of native code. It's not like that JIT generates instructions to do the cast. CPU doesn't really care :)
Mehrdad Afshari
Anyway guys, these stuff doesn't really add much value. I just submitted the answer to clarify the signed right shift fact which is *really* important to know when doing bitwise operations.
Mehrdad Afshari
@Mehrdad: That is true, I'm sure, though I would still argue for have base methods that take uint for the sake of simplicitly/elegance. Indeed, you could then overload the methods for int if you wanted to avoid constantly casting inline. These are however petty points, as you say.
Noldorin
+1 btw, since you did point out the issue with right-shifting signed ints.
Noldorin