3.1.3.2 Logic and bit operations in Python | and, or, not

Logical expressions

Let's create a variable named var and assign 1 to it. The following conditions are pairwise equivalent:
print(var > 0) print(not (var <= 0))
print(var != 0) print(not (var == 0))

You may be familiar with De Morgan's laws. They say that:
The negation of a conjunction is the disjunction of the negations.
The negation of a disjunction is the conjunction of the negations.

Let's write the same thing using Python:
not (p and q) == (not p) or (not q) not (p or q) == (not p) and (not q)
Note how the parentheses have been used to code the expressions - we put them there to improve readability.
We should add that none of these two-argument operators can be used in the abbreviated form known as op=. This exception is worth remembering.

Logical values vs. single bits

Logical operators take their arguments as a whole regardless of how many bits they contain. The operators are aware only of the value: zero (when all the bits are reset) means False; not zero (when at least one bit is set) means True.
The result of their operations is one of these values: False or True. This means that this snippet will assign the value True to the j variable if i is not zero; otherwise, it will be False.
i = 1 j = not not i

Bitwise operators

However, there are four operators that allow you to manipulate single bits of data. They are called bitwise operators.
They cover all the operations we mentioned before in the logical context, and one additional operator. This is the xor(as in exclusive or) operator, and is denoted as ^ (caret).
Here are all of them:
  • & (ampersand) - bitwise conjunction;
  • | (bar) - bitwise disjunction;
  • ~ (tilde) - bitwise negation;
  • ^ (caret) - bitwise exclusive or (xor).

Bitwise operations (&, |, and ^)
Arg AArg BArg B & Arg BArg A | Arg BArg A ^ Arg B
00000
01011
10011
11110

Bitwise operations (~)
Arg~Arg
01
10

Let's make it easier:
  • & requires exactly two 1s to provide 1 as the result;
  • | requires at least one 1 to provide 1 as the result;
  • ^ requires exactly one 1 to provide 1 as the result.


Let us add an important remark: the arguments of these operators must be integers; we must not use floats here.
The difference in the operation of the logical and bit operators is important: the logical operators do not penetrate into the bit level of its argument. They're only interested in the final integer value.
Bitwise operators are stricter: they deal with every bit separately. If we assume that the integer variable occupies 64 bits (which is common in modern computer systems), you can imagine the bitwise operation as a 64-fold evaluation of the logical operator for each pair of bits of the arguments. This analogy is obviously imperfect, as in the real world all these 64 operations are performed at the same time (simultaneously).

Comments

Popular Posts