Что делать с одиночными битами?
Теперь мы покажем вам, для чего можно использовать побитовые операторы. Представьте, что вы разработчик, которому необходимо написать важную часть операционной системы. Вам сказали, что вам разрешено использовать переменную, назначенную следующим образом:
flag_register = 0x1234
В переменной хранится информация о различных аспектах работы системы. Каждый бит переменной хранит одно значение да/нет. Вам также сказали, что только один из этих битов принадлежит Вам - третий (помните, что биты нумеруются с нуля, нулевой бит - самый младший, а самый старший - номер 31). Остальные биты не могут быть изменены, потому что они предназначены для хранения других данных. Вот Ваш бит, отмеченный буквой x
:
flag_register = 0000000000000000000000000000x000
Вы можете столкнуться со следующими задачами:
1. Проверьте состояние своего бита - Вы хотите узнать его значение; сравнение всей переменной с нулем ничего не даст, потому что оставшиеся биты могут иметь совершенно непредсказуемые значения, но вы можете использовать следующее свойство конъюнкции:
x & 1 = x
x & 0 = 0
Если вы примените операцию &
к переменной flag_register
в соответствии со следующим битовым изображением:
00000000000000000000000000001000
(обратите внимание на 1
в позиции вашего бита) в результате вы получите одну из следующих битовых строк:
00000000000000000000000000001000
если ваш бит был установлен на1
00000000000000000000000000000000
если ваш бит был сброшен на0
Такая последовательность нулей и единиц, задача которой - захватить значение или изменить выбранные биты, называется битовой маской.
Давайте создадим битовую маску для определения состояния вашего бита. Он должен указывать на третий бит. Этот бит имеет позиционный вес 23 = 8
. Подходящую маску можно создать с помощью следующей декларации:
the_mask = 8
Вы также можете составить последовательность инструкций в зависимости от состояния вашего бита:
if flag_register & the_mask:
# My bit is set.
else:
# My bit is reset.
2. Сбросьте свой бит - вы присваиваете биту ноль, в то время как все остальные биты должны оставаться неизменными; давайте использовать то же свойство конъюнкции, что и раньше, но давайте использовать немного другую маску - точно так, как показано ниже:
111111111111111111111111111101110111
Обратите внимание, что маска была создана в результате отрицания всех битов переменной the_mask
. Сброс бита прост и выглядит так (выберите тот, который вам больше нравится):
flag_register = flag_register & ~the_mask
flag_register &= ~the_mask
3. Установите свой бит - вы присваиваете своему биту 1
, в то время как все остальные биты должны оставаться неизменными; используйте следующее свойство дизъюнкции:
x | 1 = 1
x | 0 = x
Теперь вы готовы внести свой вклад, выполнив одну из следующих инструкций:
flag_register = flag_register | the_mask
flag_register |= the_mask
4. Инвертируйте свой бит - вы заменяете 1
на 0
и 0
на 1
. Вы можете использовать интересное свойство оператора xor
:
x ^ 1 = ~x
x ^ 0 = x
и инвертировали свой бит с помощью следующих инструкций:
flag_register = flag_register ^ the_mask
flag_register ^= the_mask