Bitwise Operators in Python

Learn how Python bitwise operators AND, OR, XOR, NOT, left shift, and right shift manipulate integers at the binary level, and when to use each one.

5 min read

Bitwise operators in Python work directly on the binary representation of integers, manipulating the ones and zeros that make up each number at the hardware level. While the arithmetic operators you learned earlier treat numbers as abstract values, bitwise operators let you flip individual bits, combine bit patterns, and shift entire sequences of bits left or right. These operators are less common in everyday beginner code than addition or comparison, but they are the right tool for specific tasks: setting permission flags, packing multiple small values into a single integer, working with color channels in graphics, parsing binary file formats, and implementing efficient data structures like bit arrays.

The six bitwise operators are bitwise AND written as a single ampersand, bitwise OR written as a vertical bar, bitwise XOR written as a caret, bitwise NOT written as a tilde, left shift written as two less-than signs, and right shift written as two greater-than signs. The single ampersand and vertical bar look similar to the logical and and or keywords but serve entirely different purposes. Confusing bitwise AND with logical AND is a common mistake, and understanding the difference is important before you reach the later article on common operator mistakes in Python.

How binary representation works

Every integer in Python is stored as a sequence of bits, each of which is either zero or one. The number five in binary is 101, which means one four, zero twos, and one one. The number six in binary is 110, which means one four, one two, and zero ones. Python integers have unlimited precision, so leading zeros extend as far as needed, and negative numbers use two's complement representation where the leftmost bit acts as a sign indicator and the remaining bits encode the magnitude.

Understanding the binary representation of small numbers helps you reason about what bitwise operators do, but you do not need to manually convert between decimal and binary for every operation. The built-in bin function shows the binary representation of any integer as a string, which is useful for verifying your understanding while learning. The concepts you learned about integers in integer data type in Python apply directly because bitwise operators only work with integer operands.

Bitwise AND, OR, and XOR

The bitwise AND operator compares two integers bit by bit and produces a new integer where each bit is one only when both input bits are one. The bitwise OR operator produces a one in each position where at least one input bit is one. The bitwise XOR operator, where XOR stands for exclusive OR, produces a one only when exactly one of the two input bits is one, and a zero when both are the same. These three operators are the building blocks of bit manipulation.

pythonpython
a = 5    # binary: 101
b = 6    # binary: 110
 
print(a & b)   # 4  (binary: 100, only the 4s place is 1 in both)
print(a | b)   # 7  (binary: 111, at least one 1 in each position)
print(a ^ b)   # 3  (binary: 011, positions where bits differ)

A practical application of bitwise AND is checking whether a specific flag is set in a packed integer. Operating systems and libraries often use a single integer to store multiple boolean settings by assigning each setting to a specific bit position. You check whether a setting is enabled by masking with a bitwise AND. If the result is non-zero, the flag is set. Bitwise OR sets a flag by turning on a specific bit without affecting the others. Bitwise XOR toggles a flag, flipping its current state.

Bitwise NOT

The bitwise NOT operator, written as a tilde, flips every bit of its operand. Every zero becomes a one and every one becomes a zero. Because Python integers use two's complement and have unlimited precision, the bitwise NOT of a positive number produces a negative number. The mathematical relationship is that the bitwise NOT of x equals negative x minus one. Applying the bitwise NOT to five produces negative six because flipping all bits of five in two's complement yields the representation of negative six.

pythonpython
print(~5)    # -6
print(~-1)   # 0
print(~0)    # -1

The bitwise NOT is useful for creating bitmasks that clear specific bits while preserving others. It is less common in beginner code than AND, OR, and XOR, but it appears in low-level protocols and when implementing custom numeric types that need precise bit-level control.

Left shift and right shift

The left shift operator moves all bits of the left operand to the left by the number of positions specified by the right operand. Each left shift effectively multiplies the number by two raised to the shift count, provided no bits overflow beyond the available space. The right shift operator moves bits to the right, effectively performing floor division by two raised to the shift count. These operators are fast because shifting is a native hardware instruction, and they are commonly used in performance-sensitive numeric code where multiplication and division by powers of two need to run quickly.

Shifting also appears in algorithms that pack multiple small values into a single integer. A common pattern shifts one value left by a fixed number of bits and then combines it with another value using bitwise OR. Later, the packed integer can be unpacked by shifting right and masking with bitwise AND. This technique appears in color encoding where red, green, and blue channels are packed into a single 24-bit integer, and in networking where protocol headers pack multiple fields into compact bit sequences.

Bitwise operators and precedence

Bitwise operators have their own distinct precedence levels that sit between arithmetic and comparison operators. Shifts have the highest precedence among bitwise operators, followed by bitwise AND, then bitwise XOR, and finally bitwise OR at the lowest bitwise precedence. All comparison operators, including identity and membership tests, have lower precedence than any bitwise operator. This means an expression mixing bitwise and comparison operators evaluates the bitwise operation first, but using parentheses to make the order explicit is always the safer choice.

The precedence gap between bitwise and comparison operators explains a common surprise: the expression checking whether a bitwise AND result is non-zero must be wrapped in parentheses because the comparison operators would otherwise bind more loosely and produce an unexpected grouping. The safe habit is to wrap every bitwise expression in parentheses when it appears inside a larger expression. The full precedence table is explained in the article on operator precedence in Python.

Rune AI

Rune AI

Key Insights

  • Python has six bitwise operators: AND, OR, XOR, NOT, left shift, and right shift.
  • Bitwise operators work on the binary representation of integers, not on boolean values.
  • Left shift multiplies by powers of two; right shift divides by powers of two.
  • Do not confuse the single ampersand for bitwise AND with the keyword and for logical AND.
  • Bitwise operators have their own precedence levels between arithmetic and comparison operators.
RunePowered by Rune AI

Frequently Asked Questions

Do I need to learn bitwise operators as a beginner?

Bitwise operators are less common in everyday beginner code than arithmetic or comparison operators, but they appear in specific areas like permission flags, color manipulation, network protocols, and low-level data processing. You do not need to master them on day one, but understanding what they do prepares you for those topics when they arise.

What is the difference between bitwise AND and logical AND?

Bitwise AND uses a single ampersand and operates on the individual bits of integers, returning a new integer. Logical AND uses the keyword and and operates on truthy and falsy values, returning one of the operands. They serve completely different purposes and have different precedence levels.

Why does `~5` return `-6` in Python?

Python uses two's complement representation for integers, and the bitwise NOT operator flips every bit. Since integers in Python have unlimited precision, flipping all bits of 5 (binary 101) produces a negative number in two's complement. The formula is: the bitwise NOT of x equals negative x minus one.

Conclusion

Bitwise operators manipulate the binary representation of integers. They are less common than arithmetic and logical operators in everyday code, but they are the correct tool for permission systems, bit flags, and low-level data manipulation. Understand the concepts now and reach for them when your specific problem calls for binary operations.