Bitwise Operators in Python

Bitwise Operators in Python

8 mins read732 Views Comment
Updated on Jul 13, 2022 18:15 IST

In this article, we will focus on focus on bitwise operators and understand how they perform computations in Python through examples.

2022_07_Bitwise-Operators-in-Python.jpg

In Python, operators are special characters or symbols that are used to perform arithmetic or logical operations on certain values and variables. These values that the operators operate on are known as operands.

We will be covering the following sections in this article:

What are Bitwise Operators?

Bitwise operators are used for operating on operands treating them as a string of bits. Hence, the name bitwise – stands for bit-by-bit operation. The returned output is in decimal format.

  • Bitwise Logical Operators: AND, OR, XOR, and NOT.
  • Bitwise Shift Operators: Left Shift and Right Shift.

Now, let’s discuss each bitwise operator in detail:

Recommended online courses

Best-suited Python courses for you

Learn Python with these high-rated online courses

– / –
40 hours
– / –
5 days
– / –
3 days
3 K
3 weeks
– / –
4 days
– / –
20 hours
– / –
2 months
Free
6 weeks

Bitwise Logical Operators

1. AND Operator

The bitwise AND operator, represented by the & sign, performs logical conjunction on the corresponding bits of its operands.

It returns 1 if the bits at the same position in both numbers (operands) are also 1, else returns 0. Arithmetically, this is equivalent to the intersection of the bit values:

2022_07_bit-values-2.jpg

Where ‘i’ represents the index (position) of the bits.

Let us consider the following truth table to understand this:

2022_07_and-operator-1.jpg

Let’s understand with an example in Python:

Example:

 
#bitwise AND
num1 = 9
num2 = 13
print(num1 & num2)
Copy code

Output:

 
9
Copy code

In the above code, we used the & operator between the operands num1 and num2. The operator performs the following function behind the scenes:

 
num1 = 9 -> binary representation of 9 = 1001
num2 = 13 -> binary representation of 13 = 1101
num1 & num2 = 1001 & 1101
= 1001
= 9
Copy code
2022_07_and-output.jpg

2. OR Operator

The bitwise OR operator, represented by the | sign, performs logical disjunction on the corresponding bits of its operands.

It returns 1 if either of the bits at the same position in both numbers (operands) is 1, else returns 0. Arithmetically, this is equivalent to the union of the bit values:

2022_07_or-bitwise-operator-in-Python.jpg

Where ‘i’ represents the index (position) of the bits.

This can be better understood through the following truth table:

2022_07_or-operator-truth-table.jpg

Let’s understand with an example in Python –

Example:

 
#bitwise OR
num1 = 12
num2 = 6
print(num1 | num2)
Copy code

Output:

 
14
Copy code

In the above code, we used the | operator between the operands num1 and num2. The operator performs the following function behind the scenes:

 
num1 = 12 -> binary representation of 12 = 1100
num2 = 6 -> binary representation of 6 = 0110
num1 | num2 = 1100 | 0110
= 1110
= 14
Copy code
2022_07_or-operator-example-2.jpg

3. XOR Operator

The bitwise XOR operator stands for “exclusive or” and performs exclusive disjunction on the corresponding bits of its operands.

This operator evaluates two mutually exclusive conditions and checks if exactly one of them is met – it returns 1 if one of the bits is 0 and the other is 1. If both the corresponding bits are either 0 or 1, it returns 0.

Arithmetically, this is represented as:

2022_07_xor-bitwise-operators-in-Python.jpg

Where ‘i’ represents the index (position) of the bits.

Note: In Python, modulo is represented by the % sign. Here, it performs a division between the dividend (Ai + Bi) and the divisor 2 and returns the remainder.

The XOR operation can be better understood through the following truth table:

2022_07_xor-truth-table.jpg

Let’s understand with an example in Python –

Example:

 
#bitwise XOR
num1 = 3
num2 = 10
print(num1 ^ num2)
Copy code

Output:

 
9
Copy code

In the above code, we used the ^ operator between the operands num1 and num2. The operator performs the following function behind the scenes:

 
num1 = 3 -> binary representation of 3 = 0011
num2 = 10 -> binary representation of 10 = 1010
num1 ^ num2 = 0011 ^ 1010
= 1110
= 14
Copy code
2022_07_bitwise-xor-operator-4.jpg

4. NOT Operator

The bitwise NOT operator, represented by the sign, performs logical negation on the operand by inverting all of its bits.

It works with a single operand and returns its one’s complement. – converting 1 to 0 and vice-versa. Arithmetically, this is equivalent to the subtraction of the corresponding bit values from one:

2022_07_not-operator-1.jpg

Where ‘i’ represents the index (position) of the bits.

This can be better understood through the following truth table:

2022_07_not-operator-truth-table-1.jpg

Let’s understand with an example in Python –

Example:

 
#bitwise NOT
num = 342
print(~num)
Copy code

Output:

 
-343
Copy code

In the above code, we used the operator with the operand num. The operator performs the following function behind the scenes:

 
num = 342 -> binary representation of 342 = 101010110
~num = ~101010110
= -( 1 + 010101001)
= -(101010111)
= -343
Copy code

Now that we have understood all four bitwise logical operators, let’s move on to the two bitwise shift operators:

Python Map() Function
Type Casting in Python
Understanding Literals in Python

Bitwise Shift Operators

1. Left Shift Operator

The bitwise left shift operator, represented by the << sign, shifts the bits of its first operand to the left by the number of places specified in its second operand. The operator also takes care of the gap that arises on the right edge of the new bit pattern by substituting 0s in place of the gap(s). The sign bits are not affected by the left shift operator.

When a bit shifts to the left by one place, its value doubles. Similarly, shifting a bit by two places to the left would quadruple its value. So, when you will add up all the bits in a given number, you’ll notice that the number gets doubled with every place shifted.

Let’s understand with the following examples in Python –

Example 1:

 
#bitwise left shift
num = 13
print(num << 1)
print(num << 3)
Copy code

Output 1:

 
26
104
Copy code

In the above code, we used the << operator first with operands num and 1, and then again with operands num and 3. The operator performs the following function behind the scenes:

 
num = 13 -> binary representation of 13 = 00001101
num << 1
#the bits shift left to 1 place -> 00011010 = 26
num << 3
#the bits shift left to 3 places -> 01101000 = 104
Copy code

Example 2:

 
#bitwise left shift
num = -45
print(num << 2)
Copy code

Output 2:

 
-180
Copy code

In the above code, we used the << operator first with operands num and 2. The operator performs the following function behind the scenes:

 
num = -45 -> binary representation of -45 = 10101101
num << 2
#the bits shift left to 2 places -> 10110100 = -180
Copy code

In signed binary representation, the left-most bit is considered to be the sign bit

  • If the left-most bit is 0, it is a positive number.
  • If the left-most bit is 1, it is a negative number.

Since in example 2, the left-most bit is 1, we add the ‘-’ sign to the number to make it negative. 

The bitwise right shift operator, represented by the >> sign, shifts the bits of its first operand to the right by the number of places specified in its second operand. The operator also takes care of the gap that arises on the left edge of the new bit pattern by substituting 0s in the case of a positive number and 1s if the number is negative.

When a bit shifts to the right by one place, its value has the same effect as if the number is multiplied by some power of 2.

Let’s understand with an example in Python –

Example 1:

 
#bitwise right shift
num = 120
print(num >> 1)
print(num >> 3)
Copy code

Output 1:

 
60
15
Copy code

In the above code, we used the >> operator first with operands num and 1, and then again with operands num and 3. The operator performs the following function behind the scenes:

 
num = 120 -> binary representation of 120 = 01111000
num >> 1
#the bits shift right to 1 place -> 00111100 = 60
num >> 3
#the bits shift right to 3 places -> 00001111 = 15
Copy code

Example 2:

 
#bitwise right shift
num = -10
print(num >> 2)
Copy code

Output 2:

 
-3
Copy code

In the above code, we used the >> operator first with operands num and 2. The operator performs the following function behind the scenes:

 
num = -10 -> binary representation of -10 = 11110101
num >> 2
#the bits shift right to 2 places -> 11111101 = -3
Copy code

Bitwise Operator Overloading

Python supports operator overloading. Let’s understand this concept below:

Generally, we use the ‘+’ operator to add two operands. In Python, we can use it to perform the addition operation but apart from that, we can also use the ‘+’ operator to join two Python strings or merge two Python lists.

This extended functionality of an operator beyond its operational meaning is known as operator overloading. Consider the following example:

 
a = 'Star'
b = 'bucks'
print(a + b)
Copy code

Output:

 
Starbucks
Copy code

In the above code, we used the + operator to concatenate two strings.

The bitwise operator overloading consists of three different operators:

  • Built-in Data Types
  • Third-party Modules
  • Custom Data Types

Let’s look at each of them in detail:

Built-in Data Types

From Python 3.9, the bitwise operators are defined for the following built-in data types:

  • int
  • bool
  • set and frozenset
  • dict

The bitwise operators in Python for the above data types can perform operations from set algebra, (such as union, intersection, and symmetric difference), as well as merge and update the dictionaries.

Consider a and b are Python sets, then the bitwise operators correspond to the following methods:

Set Method Bitwise Operator Representation
a.union(b) a | b
a.intersection(b) a & b
a.update(b) a | = b
a.symmetric_difference(b) ^ b
a.symmetric_difference_update(b) a ^ = b
a.intersection_update(b) a & = b

Consider the following example of two container sets with different colored balls:

 
box1 = {'blue', 'green', 'white'}
box2 = {'blue', 'red', 'yellow'}
print("Union: ", box1 | box2)
print("Intersection: ", box1 & box1)
print("Symmetric difference: ", box1 ^ box2)
print("Difference: ", box1 - box2)
Copy code

Output:

 
Union: {''red', 'white, ‘blue’, ‘green’, ‘yellow’}
Intersection: {‘green’, 'white’, ‘blue’}
symmetric difference: {'white’, ‘red’, ‘green’, ‘yellow’}
Difference: {'green', ‘white’}
Copy code

Third-part Modules

Many popular Python modules, including NumPy and Pandas, overload the bitwise operators for their specific data type.

For example, NumPy applies the operators to vectorized data in a pointwise fashion, as shown below:

 
import numpy as np
arr = np. array([2, 4, 6, 8])
print(arr << 2)
print(arr << 3)
Copy code

Output:

2022_07_third-party-modules.jpg

As you can see from the code above, we do not need to apply the << operator separately to each element of the NumPy array. This functionality can also be applied to basic Python lists.

Read more about Operators in Python

Custom Data Types

The custom data types can redefine the behavior of the Python bitwise operators where we first define a class, and then implement special methods, called magic methods, inside it.

This type of operator overloading is possible only on the newer data types. We cannot customize the behavior of the bitwise operators for existing data types.

Consider the following example:

 
a = 6
b = 2
string = 'Naukri'
print(a + b)
print(int.__add__(a,b))
print (a + string)
Copy code

Output:

2022_07_custom-data-type-1.jpg

So, for the last print statement, the code throws a TypeError because the built-in ‘int’ class does not have the add() method for the summation of ‘int’ and ‘str’ data types.

The following table gives a quick run-through of the special methods for bitwise operator overloading:

Expression Magic Method
instance & value .and(self,value)
value & instance .rand(self,value)
instance &= value .iand(self,value)
instance | value .or(self,value)
value | instance .ror(self,value)
instance|= value .ior(self,value)
instance ^ value .xor(self,value)
value ^ instance .rxor(self,value)
instance ^= value .ixor(self,value)
~instance .invert(self)
Instance << value .lshift(self,value)
value << instance .rlshift(self,value)
instance <<= value .ilshift(self,value)
instance >> value .rshift(self,value)
value >> instance .rrshift(self,value)
instance >>= value .irshift(self,value)

Endnotes

Hope this article was helpful for you to understand bitwise operators in Python. We learned about the two types of bitwise operators: Bitwise Logical Operators and Bitwise Shift Operators and how to implement them in Python. We also learned about bitwise operator overloading. Want to learn more about Python and practice Python programming? Explore related articles here.

_______________

Recently completed any professional course/certification from the market? Tell us what you liked or disliked in the course for more curated content.

Click here to submit its review with Shiksha Online

About the Author

This is a collection of insightful articles from domain experts in the fields of Cloud Computing, DevOps, AWS, Data Science, Machine Learning, AI, and Natural Language Processing. The range of topics caters to upski... Read Full Bio