Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit Setting and Bit Shifting in Ansi C

Can anyone explain this bitwise operation syntax?

#define Bitset(var,bitno) ((var) |=1UL<<(bitno))

I know it sets the bits of var, but I can't understand the syntax.

like image 763
tcop Avatar asked Jan 22 '13 20:01

tcop


Video Answer


3 Answers

Let's break it down, piece by piece:

1UL is an unsigned long int with a value of 1 represented at the bit level as:

00000000000000000000000000000001

the << is a "bit shift" operator which will move all the bits in that value above to the left bitno number of times. If it's 1UL<<5, you'll end up with:

00000000000000000000000000100000

Once you have this value, the |= (which is a bitwise OR operation with an assignment) will essentially force the bit of var that's in line with that 1 to be a 1 and wont touch any other bits because (X | 0 = X)

Lets say var is 37 and bitno is 7. Then everything at the bit level will look like this:

00000000000000000000000000100101  // var
00000000000000000000000010000000  // 1UL<<7

00000000000000000000000010100101  // var | (1UL<<7)

Finally, in case it isn't clear, the #define marks Bitset as a function-like macro.

like image 173
Foggzie Avatar answered Oct 24 '22 23:10

Foggzie


This is a macro. Whenever the preprocessor hits a statement like Bitset(var,bitno) it faithfully replaces it with

var = var | 1UL << (bitno)

Further to explain this.

UL here means Unsigned Long.

Operator | is used for bitwise OR operation. so the variable var is ORed with 1UL << bitno and assigned back to var

Then during runtime or compile time depending on the nature of the program,

Say var is 01000110 and bitno is 5

then 1UL << 5 = 32 or 00100000

then

var = 01000110 | 00100000 

ie var = 01100110

like image 31
sr01853 Avatar answered Oct 25 '22 00:10

sr01853


Say var=8, that is 0000 1000 in binary.

If you do

8 | 16 you will have 0000 1000 | 0001 0000 which will give you 0001 1000, because the | operator sets the bit if either bit is 1.

So you are applying the | operator to your value and 1<<n, that is to 0000 0001 shifted of n bits to the left.

For instance 1 << 3 is 0000 0001 << 2 = 0000 0100.

In essence: doing Bitset(8,3) will generate a mask with only the third bit set by doing 1 << 3, getting 0000 0100. It will then "or" this mask to 8, giving: 0000 1000 | 0000 0100, resulting in 0000 1100, that is, you set the 3rd bit of 8.

like image 25
nico Avatar answered Oct 25 '22 00:10

nico