When I first learn C, I found it’s hard to understand the set of bitwise operations, it took me long time to search useful resources while still don’t make sense. However my life changed until I found a famous book wrote by K&RC, The C Programming Language. It is the work of Brian Kernighan and Dennis Ritchie (who created the C language), I Strongly Recomand to Read this book if you want to learn C.
C provide six operators for bit manipulation, they are applied to integral operands, char, short, int and long:
Op. | Desc. |
---|---|
& | bitwise AND |
| | bitwise inclusive OR |
^ | bitwise exclusive OR |
<< | left shift |
>> | right shift |
~ | one’s complement (unary) |
n = n & 0177; // set to zero all but lower 7 bits
x = x | SET_ON; // sets to one in x the bits that are set to one in SET_ON
As an illustration of some of the bit operators, consider the function getbits(x,p,n) that returns the (right adjusted) n-bit field of x that begins at position p:
// getbits: get n bits from the position p
unsigned getbits(unsigned x, int p, int n) {
return (x >> (p - n + 1)) & ~(~0 << n);
}
After you finishing read of bitwise section in the book, there are three exercises that is helpful for understanding how to use those bitwise operators. I paste my solutions as follows:
Exercise 2-6. Write a function setbits(x,p,n,y) that returns x with the n bits that begin at position p set to the rightmost n bits of y, leaving the other bits unchanged.
unsigned setbits(unsigned x, int p, int n, unsigned y)
{
unsigned selectBits = ~(~0 << n) << (p - n + 1);
unsigned selectElseWhereX = x & ~selectBits;
unsigned selectY = y & selectBits;
return selectElseWhereX | selectY;
}
int main(int argc, char const *argv[])
{
int x = 0xAAFF;
int y = 0xCCBB;
// set rightmost 8 bits of x to the rightmost 8 bits of y
x = setbits(x, 7, 8, y);
printf("New x = %X", x); //0xAABB
return 0;
}
Exercise 2-7. Write a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged.
unsigned invert(unsigned x, int p, int n)
{
unsigned selectBits = ~(~0 << n) << (p - n + 1);
unsigned selectElseWhereX = x & ~selectBits;
unsigned invertBits = ~(x & selectBits) & selectBits;
return selectElseWhereX | invertBits;
}
int main(int argc, char const *argv[])
{
int x = 0xAAFFAA;
// invert 8 bits starting at position 15
x = invert(x, 15, 8);
printf("New x = %X", x); //0xAA00AA
return 0;
}
Exercise 2-8. Write a function rightrot(x,n) that returns the value of the integer x rotated to the right by n positions.
unsigned rightrot(unsigned x, int n)
{
unsigned selectBits = ~(~0 << n);
unsigned lowerToUpper = (x & selectBits) << (sizeof(x)*8 - n);
unsigned upperToLower = (x & ~selectBits) >> n;
return lowerToUpper | upperToLower;
}
int main(int argc, char const *argv[])
{
int x = 0xAABBCCDD;
// right rotate at position 12
x = rightrot(x, 12);
printf("New x = %X", x); //0xCDDAABBC
return 0;
}
If this artical is useful for you, please give me a thumbs up, thank you!