2

A solution from a top answer is

To check a bit, shift the number x to the right, then bitwise AND it:

bit = (number >> x) & 1;

That will put the value of bit x into the variable bit.

What confuses me is this, when assuming the following:

unsigned number = 5; //0101
int x = 2; //

After a shift (number >> x) we get 0001. But we shifted off bits 1 and 2 and so when we do the bitwise AND, aren't we doing it against the third bit and not the second, where x = 2? Doesn't this mean that if I want to check if bit x is set, shouldn't I do:

 bit = (number >> (x - 1)) & 1);
Community
  • 1
  • 1
8protons
  • 3,591
  • 5
  • 32
  • 67

3 Answers3

5

Yes, you are doing the bitwise AND against the third bit. Consider x to be zero-indexed, i.e. the first bit is bit 0.

ArkaneMoose
  • 111
  • 2
  • 7
  • Ah okay. I knew that we started bit indexes at `x_i : i = 0` but I didn't know that when we say "Check the second bit" in English, we actually mean check bit `x_2` where this is truly the third bit in the list – 8protons Jul 22 '16 at 17:58
  • Sorry for the additional question: so if I'm trying to check some bit flag in a register and the documentation says, "check if the 5th bit is set for this feature", do I do `(feature >> 5) & 1` or `(feature >> 4) & 1` ? – 8protons Jul 22 '16 at 18:01
  • 1
    Exactly: the second bit is bit 1... It is can be even more confusing because some people number bits from the most significant to the least significant, because that's how they appear left to right on a chart. – chqrlie Jul 22 '16 at 18:03
  • @8protons: *check if the 5th bit is set for this feature*: such wording is inherently imprecise. Look at diagrams to see how bits are numbered, hardware people usually number them from most significant to least significant, 1-based. – chqrlie Jul 22 '16 at 18:05
  • That's not consistent – kdopen Jul 22 '16 at 18:06
  • @kdopen: I agree it is not, it is not the most common choice, but is not unusual and seems more common on big-endian architectures. – chqrlie Jul 22 '16 at 18:34
2

You said:

After a shift (number >> x) we get 0001. But we shifted off bits 1 and 2 and so when we do the bitwise AND, aren't we doing it against the third bit and not the second, where x = 2? Doesn't this mean that if I want to check if bit x is set, shouldn't I do:

bit = (number >> (x - 1)) & 1);

To get the value of the 1st least significant bit, you need (number >> 0) & 1.
To get the value of the 2nd least significant bit, you need (number >> 1) & 1.
To get the value of the 3rd least significant bit, you need (number >> 2) & 1.

etc.

In other words,

1st implies 0 bits to shift
2nd implies 1 bits to shift
3rd implies 2 bits to shift
Nth implies N-1 bits to shift

I hope that makes it a little bit clearer for you.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thank you a lot. I'm basically been hung up on this small detail because I'm trying to check a register for a certain CPU feature (if it's enabled or not). The Wiki doc says, " If supported, bit 30 of the ECX register is set". So I wasn't sure if I should be doing `(ECX >> 30) & 1` or `(ECX >> 29) & 1` – 8protons Jul 22 '16 at 18:11
  • @8protons, I think `((ECX >> 29) & 1` will the right thing. – R Sahu Jul 22 '16 at 18:12
  • My bad. I reread the Intel manual and it starts from bit **00**, thus bit **30** is really the 31st bit and thus ((ECX >> 30) & 1) would work! Thank you – 8protons Jul 22 '16 at 18:22
  • @8protons, I am glad you figured out the solution. – R Sahu Jul 22 '16 at 18:24
0

The bit number represents the power of two. Thus when x is two, you are talking about bit 2 = 2**2 = 4.

The least-significant bit (or 'right most' bit if you prefer it bit 0, not bit 1.

Also, there is no reason to actually do the bit shift unless your 'bit number' is in a variable.

For example, to test bit 5 of a value, simply do

if (variable & 0x20)
    bit_is_set();

Here 0x20 is simply 2**5, (or 1 << 5)

kdopen
  • 8,032
  • 7
  • 44
  • 52