Python Bitwise Right-Shift >> Operator – Be on the Right Side of Change (original) (raw)

The Python bitwise right-shift operator x >> n shifts the binary representation of integer x by n positions to the right. It inserts a 0 bit on the left and removes the right-most bit. For example, if you right-shift the binary representation 0101 by one position, you’d obtain 0010. Semantically, the bitwise right-shift operator is the same as performing integer division by 2**n.

Python Bitwise Right-Shift >> Operator

Here’s a minimal example:

print(8 >> 1)

4

print(8 >> 2)

2

print(-3 >> 1)

-2

Let’s dive deeper into the details next!

Video Explainer

As you go over the article, you can watch my explainer video here:

Example

In this example, you apply the bitwise right-shift operator to integer 32 shifting it by one position:

x = 32

Shift by one position to the right

res = x >> 1 print(res)

16

Shift by two positions to the right

res = x >> 2 print(res)

8

The bit representation of decimal 32 is "00100000". If you shift it by one position to the right, you obtain binary "`00010000`" (decimal 16). If you shift by two positions to the right, you obtain binary "`00001000`" (decimal 8). Here’s the tabular explanation:

x 0 0 1 0 0 0 0 0
x >> 1 0 0 0 1 0 0 0 0
x >> 2 0 0 0 0 1 0 0 0

Each row represents the resulting shifted binary representation of the original integer 32.

Representing Negative Integers in Binaries

Python uses so-called complementary binaries to represent negative integers. The first bit of a complementary binary is the sign (0: positive, 1: negative). All remaining bits encode the number. You write a negative number -x as the bit pattern for (x-1) and flip all bits from 1 to 0 and from 0 to 1 (complement).

Here are two simple examples:

Let’s use this knowledge in a couple of examples to showcase the working of the bitwise XOR operator on negative integers:

Python Bitwise Right Shift on Negative Integers

Here’s the result of the bitwise right-shift operator x >> n when applied to example negative integer operands x and n:

x (int) n (int) x (binary) x >> n (binary) x >> n (int)
-1 1 11111111 11111111 -1
-2 1 11111110 11111111 -1
-4 1 11111100 11111110 -2
-4 2 11111100 11111111 -1

You can see those examples in the following script:

print(-1 >> 1)

-1

print(-2 >> 1)

-1

print(-4 >> 1)

-2

print(-4 >> 2)

-1

How to Resolve ValueError: negative shift count?

You cannot use a negative shift count, i.e., in the expression x >> n, the second operand n must be non-negative. It can be zero. If you use a negative shift count, Python raises the “ValueError: negative shift count“. To resolve it, use the left-shift operation x << n instead of using a negative shift count.

Here’s an example of the ValueError:

2 >> -1 Traceback (most recent call last): File "<pyshell#19>", line 1, in 2 >> -1 ValueError: negative shift count

And here’s an example of how to resolve it using right-shift instead of left-shift operation:

2 << 1 4

To enable the right-shift operator on your custom object, use Python’s operator overloading functionality. Overloading works through what is called magic methods or dunder methods (for “double-underscore methods”). For the right-shift operator, the magic method is the __rshift__(self, other) method. It should return a new custom object that is the result of the bitwise operation.

Here’s a short overview of the Bitwise operators’ magic methods:

Bitwise Operator Magic “Dunder” Method
& __and__(self, other)
| __or__(self, other)
^ __xor__(self, other)
~ __invert__(self)
<< __lshift__(self, other)
>> __rshift__(self, other)

Here’s an example of how to accomplish these bitwise operators on a custom class Data. We marked this respective operator in the code:

class Data:

def __init__(self, data):
    self.data = data

def __and__(self, other):
    return Data(self.data & other.data)

def __or__(self, other):
    return Data(self.data | other.data)

def __xor__(self, other):
    return Data(self.data ^ other.data)

def __invert__(self):
    return Data(~self.data)

def __lshift__(self, other):
    return Data(self.data << other.data)

def __rshift__(self, other):
    return Data(self.data >> other.data)

x = 2 y = 3 print('Operands: \n', 'x =', x, '\n', 'y =', y) print() print('Bitwise AND: ', x & y) print('Bitwise OR: ', x | y) print('Bitwise XOR: ', x ^ y) print('Bitwise NOT: ', ~x) print('Bitwise LEFT-SHIFT: ', x << y) print('Bitwise RIGHT-SHIFT: ', x >> y)

The output is:

Operands: x = 2 y = 3

Bitwise AND: 2 Bitwise OR: 3 Bitwise XOR: 1 Bitwise NOT: -3 Bitwise LEFT-SHIFT: 16 Bitwise RIGHT-SHIFT: 0

Bitwise Operators

Bitwise operators perform operations on the binary (bit) representation of integers. The following table gives a short overview of all existing bitwise operators. Note that we also provide the binary representation 100 for the decimal integer 4, and 101 for the decimal integer 5 as a comment in the right column.

Operator Name Description Example
x = 4, y = 5
& Bitwise AND Performs logical AND on a bit-by-bit basis x & y# b100 & b101 == b100 == 4
| Bitwise OR Performs logical OR operation on a bit-by-bit basis x | y# b100 b101 == b101 == 5
~ Bitwise NOT Performs logical NOT on a bit-by-bit basis, inverting each bit so that 0 becomes 1 and 1 becomes 0. Same as -x-1. ~x# -4-1 == -5
^ Bitwise XOR Performs logical “exclusive or” operation on a bit-by-bit basis x ^ y# b100 ^ b101 == b001 == 1
>> Bitwise right shift Shifts binary of left operand to the right by the number of positions specified in right operand x >> 2# b100 == b010 == b001 == 1
<< Bitwise left shift Shifts binary of left operand to the left by the number of positions specified in right operand x << 2# b100 == b1000 == b10000 == 16