oneday
oneday

Reputation: 671

Generic circular bitwise shift behavior

There are bunch of questions on circular bitwise shift behavior over here; however, even after going through them, I don't think the statement below is being raised by anyone and I am kind of confused with regard to it.

Statement on Circular Shift from Wikipedia:

/*
 * Shift operations in C are only defined for shift values which are
 * not negative and smaller than sizeof(value) * CHAR_BIT.
 */

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

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

My interpretation of above lines is — in above mentioned two conditions of shift behavior would be undefined.

However I see examples given

rotl(0x8000, -1) with answer 0x00010000.

rotl(8,-1) with answer 16.

What is the right way to deal with such shift parameters (i.e. negative and greater than number of bits)? Am I misinterpreting something?

Upvotes: 0

Views: 125

Answers (1)

dlask
dlask

Reputation: 8982

#define CHAR_BITS  ( 8 )
#define UINT_BITS  ( sizeof(unsigned int) * CHAR_BITS )

// We need modulo, not remainder. This is a way to obtain it.
int mod(int x, int m) {
    return ((x % m) + m) % m;
}

// Calculate left rotation for any shift value.
unsigned int rotl(unsigned int value, int shift) {
    int lshift = mod(shift, UINT_BITS);
    return (value << lshift) | (value >> (UINT_BITS - lshift));
}

Upvotes: 1

Related Questions