Получение определенного значения бита в байтовой строке - PullRequest
5 голосов
/ 07 апреля 2010

В байтовой строке имеется байт по определенному индексу, который представляет восемь флагов; один флаг на бит в байте. Если флаг установлен, его соответствующий бит равен 1, в противном случае - 0. Например, если у меня есть

b'\x21'

флаги будут

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

Каков наилучший способ получить значение каждого бита в этом байте, поэтому я знаю, установлен определенный флаг или нет? (Предпочтительно с использованием побитовых операций)

Ответы [ 3 ]

26 голосов
/ 07 апреля 2010

Как правило, самый младший бит - это битовый индекс 0, а самый старший бит - это битовый индекс 7. Используя эту терминологию, мы можем определить, установлен ли битовый индекс k, взяв поразрядно, а 1 сдвинут влевопо к.Если побитовый и ненулевой, то это означает, что индекс k имеет 1;в противном случае индекс k имеет значение 0. Итак:

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

Это будет правильно определять значение битов в индексах 0 ... 7 байта, идущих справа налево (т.е. наименее значимыхбит к старшему значащему биту или, что то же самое, от 1-го места до 2 7 = 128).

Почему это работает Я решил добавить объяснение, почему это работает ...

1 << 0 равно 1 = 0000 00011 << 1 равно 2 = 0000 00101 << 2 равно 4 = 0000 0100</p>

Как видите, 1 <

6 голосов
/ 07 апреля 2010

х & 1, х & 2, х & 4, х & 8 и т. Д.

если они> 0, то бит 1,2,3,4 и т. Д. Установлен

3 голосов
/ 07 апреля 2010

Укажите битовые маски (читайте о битовых масках в Википедии ):

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

А затем используйте AND, чтобы проверить, установлен ли бит (flags содержит ваш байт):

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

}
...

Конечно, вы должны назвать FLAG_1, etc чем-то значимым, в зависимости от контекста. Например. ENABLE_BORDER.

Обновление:
Я был озадачен вашим комментарием, какие биты установлены, но после прочтения другого ответа я понял, что вы считаете биты с неправильного конца. Биты нумеруются с нуля справа.

...