Логические выражения
Давайте создадим переменную с именем var
и присвоим ей 1
. Следующие условия попарно эквивалентны:
# Пример 1:
print(var > 0)
print(not (var <= 0))
# Пример 2:
print(var != 0)
print(not (var == 0))
Возможно, вы знакомы с законами Де Моргана. Они говорят, что:
Отрицание конъюнкции - это дизъюнкция отрицаний.
Отрицание дизъюнкции - это конъюнкция отрицаний.
Напишем то же самое на Python:
not (p and q) == (not p) or (not q)
not (p or q) == (not p) and (not q)
Обратите внимание, как круглые скобки использовались для кодирования выражений - мы поместили их туда, чтобы улучшить читаемость.
Следует добавить, что ни один из этих операторов с двумя аргументами нельзя использовать в сокращенной форме, известной как op=
. Об этом исключении стоит помнить.
Логические значения и отдельные биты
Логические операторы принимают аргументы как единое целое независимо от того, сколько битов они содержат. Операторам известно только значение: ноль (когда все биты сброшены) означает False
; ненулевое значение (если установлен хотя бы один бит) означает True
.
Результатом их операций является одно из следующих значений: False
или True
. Это означает, что этот фрагмент кода присвоит значение True
переменной j
, если i
не равно нулю; в противном случае будет False
.
i = 1
j = not not i
Побитовые операторы
Однако есть четыре оператора, которые позволяют манипулировать отдельными битами данных. Они называются побитовыми операторами.
Они охватывают все упомянутые ранее операции в логическом контексте и один дополнительный оператор. Это оператор xor
(как в исключающем или), он обозначается как ^
(карет).
Вот они все:
&
(амперсанд) ‒ побитоваая конъюнкция;|
(вертикальная черта) ‒ побитоваая дизъюнкция;~
(тильда) ‒ побитовое отрицание;^
(карет) ‒ побитовое исключающее или (xor).
Аргумент A |
Аргумент B |
A & B |
A | B |
A ^ B |
---|---|---|---|---|
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
Аргумент | ~ Аргумент |
---|---|
0 |
1 |
1 |
0 |
Давайте сделаем проще:
&
требует ровно два бита1
для предоставления в качестве результата1
;|
требует хотя бы одного бита1
для предоставления1
в качестве результата;^
требует ровно одного бита1
для предоставления1
в качестве результата.
Добавим важное замечание: аргументы этих операторов должны быть целыми числами; мы не должны использовать здесь числа с плавающей запятой.
Важна разница в работе логических и битовых операторов: логические операторы не проникают на битовый уровень своего аргумента. Их интересует только конечное целочисленное значение.
Побитовые операторы более строгие: они обрабатывают каждый бит отдельно . Если мы предположим, что целочисленная переменная занимает 64 бита (что является обычным явлением в современных компьютерных системах), вы можете представить поразрядную операцию как 64-кратную оценку логического оператора для каждой пары битов аргументов. Эта аналогия явно несовершенная, поскольку в реальном мире все эти 64 операции выполняются в одно и то же время (одновременно).