Получение определенного битового значения в строке байтов

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

b'\x21'

флаги были бы

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

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

5
задан 7 April 2010 в 10:34
поделиться

3 ответа

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

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

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

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

1 << 0 равно 1 = 0000 0001
1 << 1 равно 2 = 0000 0010
1 << 2 равно 4 = 0000 0100

Как вы можете видеть, что 1 << k эквивалентно 2 k и содержит 1 именно в том индексе, который нас интересует, и нигде в другом месте. Следовательно, побитовое и с 1 << k вернет либо 0, либо 1 << k; он будет 0, если бит в интересующем нас индексе равен 0 (потому что 1 и 0 равны 0, а все другие биты в 1 << k равны нулю). Если интересующий нас бит равен 1, то мы получаем 1 и 1 в этой позиции, а также 0 и что-то еще везде.

26
ответ дан 18 December 2019 в 05:28
поделиться

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

, если они> 0 то устанавливается бит 1,2,3,4 и т. д.

6
ответ дан 18 December 2019 в 05:28
поделиться

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

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

А затем используйте И , чтобы проверьте, установлен ли бит ( 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 и т.д. чем-нибудь значимым, в зависимости от контекста. Например. ENABLE_BORDER .

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

3
ответ дан 18 December 2019 в 05:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: