Getting a specific bit value in a byte string

The byte string contains a byte with a specific index that represents eight flags; one byte per bit in a byte. If the flag is set, the corresponding bit is 1, otherwise - 0. For example, if I have

b'\x21' 

flags will be

 0001 0101 # Three flags are set at indexes 0, 2 and 4 # and the others are not set 

What would be the best way to get each bit value in this byte, so I know if a certain flag is set or not? (Preferred use of bitwise operations)

+4
source share
3 answers

As a rule, the least significant bit is index bit 0, and the most significant bit is index bit 7. Using this terminology, we can determine if bit index k is set, bitwise and with 1 shifted to the left by k. If bitwise and non-zero, then this means that the index k has 1; otherwise, the index k has a value of 0. So:

  def get_bit (byteval, idx):
     return ((byteval & (1 << idx))! = 0);

This will correctly determine the value of the bits from the 0 ... 7 byte indices going from right to left (i.e., the least significant bit to the most significant bit or equivalently from 1st place to 2 7 = 128th place).

Why does it work
I decided that I should add an explanation of why it works ...

1 <0 - 1 = 0000 0001
1 <1 is 2 = 0000 0010
1 <2 is 4 = 0000 0100

As you can see, 1 <k is equivalent to 2 k and contains 1 in the index that interests us exactly and in no other place. Therefore, bitwise and with 1 <k will either return 0 or 1 <k; it will be 0 if the bit in the index of interest to us is 0 (because 1 and 0 are 0, and all other bits in 1 <k are equal to zero). If the bit that we are interested in is 1, then we get 1 and 1 at that position, and 0 and something else, everywhere.

+23
source

x and 1, x and 2, x and 4, x and 8, etc.

if they are 0, then bit 1,2,3,4, etc. installed

+6
source

Specify bit masks (read about bit masks on Wikipedia ):

 FLAG_1 = 1 # 0000 0001 FLAG_2 = 2 # 0000 0010 FLAG_3 = 4 # 0000 0100 ... 

and then AND to check if the bit is set ( flags contains its byte):

 if(flags & FLAG_1) { # bit 0 is set, example: 0001 0101 & 0000 0001 = 0000 0001 } if(flags & FLAG_2) { # bit 1 is set, example: 0001 0101 & 000 0010 = 0000 0000 } ... 

Of course, you should call FLAG_1, etc something meaningful, depending on the context. For instance. ENABLE_BORDER .

Update:
I was confused by your comment about which bits were set, but after reading another answer, I realized that you are counting the bit from the wrong end. Bits are numbered with zeros to the right.

+3
source

Source: https://habr.com/ru/post/1306212/


All Articles