Bit Manipulation Operators

We've already seen the usual math operators: +, -, *, /, %, **; as well as the abs( x ) and pow( x , y ) functions. There are several other operators available to us. Principally, these are for manipulating the individual bits of an integer value.

The unary ~ operator flops all the bits in a plain or long integer. 1's become 0's and 0's become 1's. Since most hardware uses a technique called 2's complement, this is mathematically equivalent to adding 1 and switching the number's sign.

>>> 
print ~0x12345678

-305419897

There are binary bit manipulation operators, also. These perform simple Boolean operations on all bits of the integer at once.

The binary & operator returns a 1-bit if the two input bits are both 1.

>>> 
print 0&0, 1&0, 1&1, 0&1

0 0 1 0

Here's the same kind of example, combining sequences of bits. This takes a bit of conversion to base 2 to understand what's going on.

>>> 
print 3&5

1

The number 3, in base 2, is 0011. The number 5 is 0101. Let's match up the bits from left to right:

  0 0 1 1
& 0 1 0 1
  -------
  0 0 0 1

The binary ^ operator returns a 1-bit if one of the two inputs are 1 but not both. This is sometimes called the exclusive or.

>>> 
print 3^5

6

Let's look at the individual bits

  0 0 1 1
^ 0 1 0 1
  -------
  0 1 1 0

Which is the binary representation of the number 6.

The binary | operator returns a 1-bit if either of the two inputs is 1. This is sometimes called the inclusive or. Sometimes this is written and/or .

>>> 
print 3|5

7
>>>

Let's look at the individual bits.

  0 0 1 1
| 0 1 0 1
  -------
  0 1 1 1

Which is the binary representation of the number 7.

There are also bit shifting operations. These are mathematically equivalent to multiplying and dividing by powers of two. Often, machine hardware can execute these operations faster than the equivalent multiply or divide.

The << is the left-shift operator. The left argument is the bit pattern to be shifted, the right argument is the number of bits.

>>> 
print 0xA << 2

40

0xA is hexadecimal; the bits are 1-0-1-0. This is 10 in decimal. When we shift this two bits to the left, it's like multiplying by 4. We get bits of 1-0-1-0-0-0. This is 40 in decimal.

The >> is the right-shift operator. The left argument is the bit pattern to be shifted, the right argument is the number of bits. Python always behaves as though it is running on a 2's complement computer. The left-most bit is always the sign bit, so sign bits are shifted in.

>>> 
print 80 >> 3

10

The number 80, with bits of 1-0-1-0-0-0-0, shifted right 3 bits, yields bits of 1-0-1-0, which is 10 in decimal.

There are some other operators available, but, strictly speaking, they're not arithmetic operators, they're logic operations. We'll return to them in Chapter 7, Truth, Comparison and Conditional Processing .