Simple circular bit shifts, in C++

MosaicFuneral 0 Tallied Votes 995 Views Share

Occasionally there's times when you want to shift a bit over, but you would like to preserve the end of it, for one reason or another.
Such as with say you have: 10000001 but you would like: 00000011 then latter on back to: 10000001 Or in Dec 129-into-3, and 3-into-129.

On x86's there is an instruction for it, but I doubt if it's portable.
So how to do it with just the basic bit operators? Here's how to c-shift one bit left, with an 8-bit unsigned char:

unsigned char c = value; /*0-255*/
unsigned char d = c >> 7;
c <<= 1;
c |= d;

Yep, just three simple bit-operations.
The temporary('d') holds the left-most bit, the value('c') is shifted over, then the left-most bit that was OR'ed onto the end-bit.
(Warning: I might be thinking backwards, and explaining this a bit wrong.)

Below I have a 8-bit value that circular-shifts a 9 times around, then 9 times back; and a 32-bit value that cirular-shifts around 65 times, then 65 back.
You may want to find the Dec-Bin funtion and print that, so you can view it a little more easily.

For future reference, you may wish to use a value return instead of an address, also perhaps an overloaded version that takes an extra parameter for looping the shift; instead of manually doing it:

unsigned char Left(unsigned char c, int shift)
{
    unsigned char d;

     for(int i = 0; i < shift; i++)
     {
          d = c >> 7;
          c <<= 1;
          c |= d;
     }

     return(c);
}

I have not tested the above function with the loop inside, test it first.

I have also only tested this program on Dev-C++, was going to do a few others, but I'd have to reinstall those; meaning, it should work, just let me know it it doesn't.
Output should be:
129
3
129

513
1026
513

#include <iostream>
#include <cstdlib> /*I like getchar()*/
using namespace std;

void Left(unsigned char &c)
{
     unsigned char d = c >> 7;
     c <<= 1;
     c |= d;
}

void Right(unsigned char &c)
{
     unsigned char d = c << 7;
     c >>= 1;
     c |= d;
}

void Left(unsigned int &i)
{
     unsigned int d = i >> 31;
     i <<= 1;
     i |= d;
}

void Right(unsigned int &i)
{
     unsigned int d = i << 31;
     i >>= 1;
     i |= d;
}

int main()
{
    
    unsigned char a = 129;
    unsigned int  b = 513;

    /*8bit*/

    cout << "No shift: " << endl;
    cout << endl << (int)a;
    cout << endl << "Left: " << endl;
    
    for(int i = 0; i < 9; i++) { Left(a); }
    cout << endl << (int)a;
    cout << endl << "Right: " << endl;
    
    for(int i = 0; i < 9; i++) { Right(a); }
    cout << endl << (int)a << endl;
    
    /*32bit now*/
    
    cout << "No shift: " << endl;
    cout << endl << b;
    cout << endl << "Left: " << endl;
    
    for(int i = 0; i < 65; i++) { Left(b); }
    cout << endl << b;
    cout << endl << "Right: " << endl;
    
    for(int i = 0; i < 65; i++) { Right(b); }
    cout << endl << b << endl;
    
    getchar();
    return(0);
}