Bitwise rotation (circular shift)

I tried to do C ++ code about bitwise rotation, and I would like to do it left shifted. I did not know how to encode this, but I found a small code on Wikipedia like this.

unsigned int rotl(unsigned int value, int shift) { return (value << shift) | (value >> (sizeof(value) * CHAR_BIT - shift)); } 

Then I tried to make it work, but this code does not give the result that I expected. Ex. I have unsigned int 12 , in binary format 1100, and when I want to perform bitwise rotation on the left screen using the code above, the output will be unsigned int 24 , (11000), and it should give unsigned int 9 , therefore what if I do a bitwise rotation (left shifted), the first bit of the MSB should now be the first bit, and all the other bits should move one bit to the left.

Can you help me understand what the problem is? or if I am doing something wrong.

Thanks.

+5
source share
4 answers

The following code works fine

 #include <cstdint> std::uint32_t rotl(std::uint32_t v, std::int32_t shift) { std::int32_t s = shift>=0? shift%32 : -((-shift)%32); return (v<<s) | (v>>(32-s)); } std::uint32_t rotr(std::uint32_t v, std::int32_t shift) { std::int32_t s = shift>=0? shift%32 : -((-shift)%32); return (v>>s) | (v<<(32-s)); } 

and of course a test for him.

 #include <iostream> int main(){ using namespace std; cout<<rotr(8,1)<<endl; // 4 cout<<rotr(8,-1)<<endl; //16 cout<<rotl(8,1)<<endl; //16 cout<<rotl(8,-1)<<endl; //4 cout<<rotr(4,60)<<endl; //64 cout<<rotr(4,61)<<endl; //32 cout<<rotl(4,3)<<endl; //32 cout<<rotl(4,4)<<endl; //64 return 0; } 

I may not have provided the fastest implementation, but portable and stable for sure

General version

 #include <cstdint> template< class T> inline T rotl( T v, std::int32_t shift){ std::size_t m = sizeof(v)*std::numeric_limits<T>::digits; T s = shift>=0? shift%m: -((-shift)%m) return (v<<s) | (v>>(ms)); } template< class T> inline T rotr( T v, std::int32_t shift){ std::size_t m = sizeof(v)*std::numeric_limits<T>::digits; T s = shift>=0? shift%m: -((-shift)%m) return (v>>s) | (v<<(ms)); } 

Greetings :)

+6
source

This is because you are using an int , which is 32 bits, so it worked as expected by packing the most significant bits in the foreground. Use a smaller data structure such as unsigned char to make it more manageable.

0
source

You have more than 4 bits in your integers, most likely 32, but could theoretically be 64 or 16. So, your bits for value 12 are 00000000000000000000000000001100. Performing a left rotation of 1 will naturally give you a value of 00000000000000000000000000011000 (= 24) .

0
source

if you want bitwise rotation in an arbitrary number of bits (for example, 4), just add a parameter to your function:

 unsigned int rotl(unsigned int value, int shift, unsigned int width) { return ((value << shift) & (UINT_MAX >> (sizeof(int) * CHAR_BIT - width))) | (value >> (width - shift)); } 
0
source

Source: https://habr.com/ru/post/1202391/


All Articles