Introduction
Have you ever seen symbols like &
, |
, ^
, or ~
in Python and wondered what they actually do? You’re not alone! These are bitwise operators, and they might seem confusing at first, but once you break them down, they’re easier to understand than you think.
Bitwise operators work with binary numbers, which are just 1s and 0s. Every number in Python can be represented as a series of these 1s and 0s in the computer’s memory. When we use bitwise operators, we’re doing operations directly on those 1s and 0s.
In this blog post, I’ll explain what each bitwise operator does in simple terms, and we’ll go through clear Python examples to help you understand them.
By the end, you’ll see how and when to use bitwise operators in your own code. Let’s start by looking at the first one: the AND (&
) operator.

The AND (&
) Operator
Imagine you have two numbers, like 12 and 5. When we talk about bitwise operators, we’re working with binary numbers. Binary is just another way to write numbers, using only 1s and 0s. It’s how computers represent everything!
So, to understand how the AND operator (&
) works, we need to convert the numbers into binary.
Here’s the breakdown:
- The number 12 in binary is 1100.
- The number 5 in binary is 0101.
Now, we apply the AND operator. The AND operator checks each bit, one by one. It only keeps a 1 if both bits are 1. If either bit is 0, it will return 0.
Let’s look at it in detail:
1100 (This is 12 in binary)
& 0101 (This is 5 in binary)
-------
0100 (This is 4 in binary, which is our result)
Step-by-Step Explanation:
- Compare the first bit on the left:
We have 0 in the first position for 12 and 1 in the first position for 5.
Since 12 and 5 have 0 and 1, the result is 0. - Move to the second bit:
The second bit is 0 for both 12 and 5.
Since they’re both 0, the result here is 0. - Third bit:
The third bit is1
for both 12 and 5.
Since they’re both 1, the result is 1. - Fourth bit:
The fourth bit is 1 for 12 and 0 for 5.
Since 12 and 5 have 0 and 1, the result is 0.
So, when you compare the two binary numbers bit by bit, the final result is 0100
, which equals 4 in decimal.
Python Code Example:
Let’s take the same example and run it in Python:
a = 12 # 1100 in binary
b = 5 # 0101 in binary
# Using the AND operator
result = a & b
print(result) # This prints 4
When you run this code, it will output 4, just like we calculated.
Key Takeaways:
- The AND (
&
) operator compares each bit in two numbers. - It only gives a result of 1 if both bits are 1.
- If either bit is 0, the result is 0.
The OR (|
) Operator: How It Works
Think of the OR operator as saying, “I’ll keep the bit as 1 if either of the bits is 1.” So, unlike the AND operator, the OR operator is more lenient. If one of the bits is a 1, it keeps it as 1.
Let’s break it down with an example:
Imagine we have 12 and 5 again. In binary:
- 12 is 1100
- 5 is 0101
Now, let’s use the OR operator (|
) to compare these two numbers:
1100 (12 in binary)
| 0101 (5 in binary)
-------
1101 (13 in binary)
Step-by-Step Explanation:
- First bit comparison:
The first bit is1
for 12 and 0 for 5, Since at least one of them is 1, the result is 1. - Second bit comparison:
The second bit is1
for both 12 and 5. So the result is 1. - Third bit comparison:
The third bit is0
for both numbers. Since both bits are 0, the result is 0. - Fourth bit comparison:
The fourth bit is0
for 12 and1
for 5. Since at least one of them is 1, the result is 1.
So, the final result is 1101
, which is 13 in decimal.
Python Code Example:
Here’s how you can do this in Python:
a = 12 # 1100 in binary
b = 5 # 0101 in binary
# Using the OR operator
result = a | b
print(result) # This prints 13
When you run the code, the output will be 13.
Key Takeaways:
- The OR (
|
) operator compares two bits. - It results in 1 if either of the bits is 1.
- It only gives 0 if both bits are 0.
The XOR (^
) Operator: What It Does
The XOR (exclusive OR) operator is a bit different from both AND and OR. It works like this:
“I’ll keep the bit as 1 if one of the bits is 1, but not both.”
In other words, if both bits are the same (both 0 or both 1), the result is 0. But if the bits are different (one is 0 and the other is 1), the result is 1.
Let’s break it down using 12 and 5 again:
- 12 is 1100 in binary
- 5 is 0101 in binary
Now, let’s apply the XOR operator (^
):
1100 (12 in binary)
^ 0101 (5 in binary)
-------
1001 (9 in binary)
Step-by-Step Explanation:
- First bit comparison:
The first bit is1
for 12 and0
for 5. Since they are different, the result is 1. - Second bit comparison:
The second bit is1
for both numbers. Since they are the same, the result is 0. - Third bit comparison:
The third bit is0
for both numbers. Since they are the same, the result is 0. - Fourth bit comparison:
The fourth bit is0
for 12 and1
for 5. Since they are different, the result is 1.
So, the final result is 1001
, which is 9 in decimal.
Python Code Example:
Here’s how you can do this in Python:
a = 12 # 1100 in binary
b = 5 # 0101 in binary
# Using the XOR operator
result = a ^ b
print(result) # This prints 9
When you run the code, the output will be 9.
Key Takeaways:
- The XOR (
^
) operator compares two bits. - It results in 1 if the bits are different (one is 1, the other is 0).
- It results in 0 if the bits are the same (both 0 or both 1).
The NOT (~
) Operator: What It Does

The NOT operator is a little different from the others we’ve covered. While the AND, OR, and XOR operators work between two numbers, the NOT operator only works on one number.
It’s also called the bitwise NOT operator, and its job is to flip every bit. If a bit is 1, it becomes 0. If it’s 0, it becomes 1.
In simple terms, the NOT operator inverts the bits of the number.
But there’s a catch—Python uses something called two’s complement representation to handle negative numbers. This means the result of the NOT operator isn’t as simple as just flipping the bits, but I’ll explain that.
Let’s break it down with an example.
Example: Understanding Bitwise NOT
Let’s take the number 12 and apply the NOT operator on it.
- 12 in binary is:
00000000 00000000 00000000 00001100
(Here I’m showing a 32-bit representation, but in Python, it uses whatever bit length is needed.) - Applying the NOT operator (
~12
):
It flips every bit, so the binary representation becomes:11111111 11111111 11111111 11110011
Now, when we convert this result back into decimal, we get -13.
Why does this happen?
Python uses two’s complement to represent negative numbers. Flipping the bits of a positive number doesn’t just give you the negative version directly. Instead, the result is the negative of the number minus 1.
- For example, ~12 gives us -13 because flipping the bits of 12 gives us the binary representation of -13 in two’s complement.
Python Code Example:
Let’s see this in Python:
a = 12
# Using the NOT operator
result = ~a
print(result) # This prints -13
When you run this code, the output will be -13.
What’s Happening Behind the Scenes?
Here’s a quick breakdown of the steps:
- 12 in binary:
00000000 00000000 00000000 00001100
- Flip all bits:
11111111 11111111 11111111 11110011
- This binary value represents -13 in two’s complement.
Key Takeaways:
- The NOT (
~
) operator flips every bit in a number. - If a bit is 1, it becomes 0.
- If a bit is 0, it becomes 1.
- Python uses two’s complement to represent negative numbers, so flipping the bits of a number results in a negative value.
Must Read
- How to Use Bitwise Operators in Python with Step-by-Step Code Examples
- What Are Membership Operators in Python and How Do They Work?
- What Are Identity Operators in Python? Full Guide with Code
- Mastering Logical Operators in Python: The Ultimate Beginner- Guide
- Mastering Multiple Inputs in Python
Bitwise Shift Operators: <<
(Left Shift) and >>
(Right Shift)
The shift operators allow you to move the bits of a number to the left or right. When you shift the bits, you’re essentially multiplying or dividing the number by powers of 2.
There are two types of shift operators:
- Left Shift (
<<
) - Right Shift (
>>
)
Let’s go over both one by one.

Left Shift (<<
) Operator
The left shift (<<
) operator shifts all the bits in a number to the left. Each shift to the left multiplies the number by 2.
For example, let’s say we have the number 3. In binary, 3 is represented as 0011.
Example:
Let’s shift 3 to the left by one position:
- 3 in binary:
0011
- After shifting left by 1 (
3 << 1
), the bits move to the left and a 0 is added on the right:0110
In decimal, 0110
is 6, so 3 << 1 gives us 6.
Code Example:
a = 3
result = a << 1
print(result) # This prints 6
Now, let’s break down the shift:
- Shift Left by 1 multiplies the number by 2. So,
3 << 1
is 3 * 2 = 6.
If you shift to the left again:
- 3 << 2 would multiply 3 by 4, giving you 12 (since 2 shifts left is multiplying by 2^2 = 4).
Right Shift (>>
) Operator
The right shift (>>
) operator does the opposite. It shifts the bits to the right, which divides the number by 2 for each shift.
Let’s take 12 as an example. In binary, 12 is 1100.
Example:
Let’s shift 12 to the right by one position:
- 12 in binary:
1100
- After shifting right by 1 (
12 >> 1
), the bits move to the right and a 0 is added on the left:0110
In decimal, 0110
is 6, so 12 >> 1 gives us 6.
Code Example:
a = 12
result = a >> 1
print(result) # This prints 6
Again, here’s what happened:
- Shift Right by 1 divides the number by 2. So,
12 >> 1
is 12 / 2 = 6.
If you shift to the right again:
- 12 >> 2 would divide 12 by 4, giving you 3 (since 2 shifts right is dividing by 2^2 = 4).
Key Takeaways:
- Left Shift (
<<
): Shifting left by one position multiplies the number by 2. - Right Shift (
>>
): Shifting right by one position divides the number by 2.
The shift operators are useful when you want to scale numbers by powers of 2 efficiently.
When to Use Bitwise Operators in Real Projects
1. Low-Level Data Manipulation
This is when you work directly with the bits of data. Bits are the smallest unit of data (just a 0 or 1), and sometimes you need to get super specific and manipulate the data at this level.
Example:
Let’s say you’re working with a sensor in an embedded system. The sensor might send data in a binary format. For example, the sensor could send a status code where each bit represents a different status:
- Bit 1 = Temperature is above threshold
- Bit 2 = Humidity is high
- and Bit 3 = System is in error mode
You want to quickly check these individual statuses by manipulating the bits.
Bitwise Operators make this easy:
- AND (
&
) to check a specific bit in the status code. - Use OR (
|
) to set a specific bit to 1 (e.g., turn on a warning). - Use XOR (
^
) to toggle a bit (flip it from 0 to 1 or 1 to 0).
Example in code:
Let’s assume the sensor status is represented as status_code = 0b010
(which is 2
in decimal).
- Bit 1: Off (0)
- Bit 2: On (1)
- and Bit 3: Off (0)
To check if the second bit (humidity status) is on:
status_code = 0b010
humidity_status = status_code & 0b010 # This will return 0b010, meaning True (humidity is high)
if humidity_status:
print("Humidity is high")
2. Binary Flags in Configuration
A binary flag is just a fancy name for a bit used to represent a setting or configuration. Imagine you’re building an app or a piece of software where several features can be enabled or disabled.
Example:
You might store the status of multiple features in a single number. Each feature gets its own bit, and if the bit is 1
, the feature is enabled; if it’s 0
, it’s disabled.
Let’s say we have these three settings:
- Feature 1: Notifications (bit 0)
- Feature 2: Dark Mode (bit 1)
- and Feature 3: Auto-Updates (bit 2)
You can store these features in a single integer (let’s say settings = 0b011
), where:
- Bit 0 = Notifications (On)
- Bit 1 = Dark Mode (On)
- and Bit 2 = Auto-Updates (Off)
Code example to update settings:
settings = 0b011 # Notifications and Dark Mode are enabled
# Turn off Dark Mode (bit 1)
settings &= ~0b010 # Now settings becomes 0b001 (only Notifications are on)
# Check if Notifications are enabled (bit 0)
if settings & 0b001:
print("Notifications are enabled")
This way, you store and check many settings using just a few bits instead of multiple variables.
3. Performance-Critical Code
Sometimes, you’re building applications that need to run super fast — for example, in games, networking (where speed is important), or real-time systems. Bitwise operations can make your code run faster than other methods like if
statements or loops.
Why? Because bitwise operators are very efficient for computers to process. They are literally just manipulating bits, and that’s much faster than checking conditions or doing math.
Example:
If you need to check multiple flags or states in real-time (like in a game), using bitwise operators is way faster than having multiple if
statements.
Imagine you’re building a simple game where a character can be in different states (running, jumping, or idle). Instead of using a bunch of if
conditions, you can store these states as bits and quickly check them with bitwise operators.
# States stored as bits
states = 0b011 # Running (bit 1), Jumping (bit 0)
# Check if character is running
if states & 0b010:
print("Character is running")
# Check if character is jumping
if states & 0b001:
print("Character is jumping")
Each check is super fast, and you don’t need to go through a bunch of if
statements to figure out what the character is doing.
4. Encryption & Compression Algorithms
Bitwise operators are also used in encryption (scrambling data) and compression (reducing the size of data). These operations often work directly with the bits of the data, making them a perfect match.
Example:
In encryption algorithms like XOR, data is scrambled by flipping bits. Here’s a simple example of how XOR can be used for encryption:
- You take the data (say,
42
), and apply the XOR operator with a key (say,56
). - You get an encrypted value.
- and You can decrypt the data by applying the XOR again with the same key.
# Encryption example using XOR
original_data = 42
key = 56
# Encrypt data
encrypted_data = original_data ^ key
print(f"Encrypted Data: {encrypted_data}")
# Decrypt data
decrypted_data = encrypted_data ^ key
print(f"Decrypted Data: {decrypted_data}")
This is just a basic concept, but in real encryption, bitwise operations are used to secure data by mixing it up in a complex way.
When Should You Use Bitwise Operators?
- Working with low-level systems: If you’re writing firmware or dealing with hardware that communicates through bits, bitwise operators are essential.
- Storing and managing configuration flags: When you need to store multiple settings or states in a single number, using bitwise operations makes it simple and fast.
- Optimizing performance: For tasks that need to be fast, like game development or real-time applications, bitwise operators are your friend.
- Encryption and compression: If you’re building systems that need to secure or compress data, bitwise operators are often at the core of these algorithms.
Handy Python Tips for Bitwise Operations
1. Use bin()
to See the Binary Version
Sometimes it’s hard to understand what a number looks like in binary. Python has a built-in way to help: bin()
.
Example:
a = 5
print(bin(a)) # Output: '0b101'
The '0b'
means “this is a binary number.”
So 5
in binary is 101
.
Let’s try another:
b = 3
print(bin(b)) # Output: '0b11'
That’s 3
in binary — 11
.
Now if you do a & b
:
print(a & b) # Output: 1
print(bin(a & b)) # Output: '0b1'
You can see exactly why the answer is 1
.
Binary math:
101 (which is 5)
& 011 (which is 3)
= 001 (which is 1)
Using bin()
helps you understand what’s going on.
2. Use Parentheses for Clear Code
In Python, when you write something like this:
result = a & b | c
Python might do b | c
first, depending on the order of operations.
To avoid confusion, add parentheses:
result = (a & b) | c
Now you’re telling Python:
“First do
a & b
, then OR the result withc
.”
Simple rule: when using multiple operators together, just use brackets to make it clear what you want.
3. Use Masking to Check, Set, or Clear Bits

Let’s say you’re working with flags — like on/off switches inside one number.
Imagine this:
flags = 0b1010 # binary: 1010 (which is 10 in decimal)
Now:
To check if bit 1 is ON:
mask = 0b0010 # Only bit 1 is ON
if flags & mask:
print("Bit 1 is ON")
You’re using &
to test a specific bit.
To turn ON bit 0:
flags = flags | 0b0001
Now bit 0 is ON. That’s how you set a bit.
To turn OFF bit 3:
flags = flags & ~0b1000
The ~
flips the bits — so this removes bit 3.
In short:
- Use
bin()
to see the bits clearly. - Use parentheses to keep control of your logic.
- and Use masking to check or change just the bits you care about.
Build Small Settings System using Flags
let’s build a small settings system using flags. I’ll walk you through it step by step, and you’ll see how bitwise operations help manage multiple settings using just one number.
Goal:
Let’s say we have 4 settings (each one can be ON or OFF):
Setting | Bit Position | Binary |
---|---|---|
Notifications ON | bit 0 | 0001 |
Dark Mode ON | bit 1 | 0010 |
Location Access ON | bit 2 | 0100 |
Auto-Update ON | bit 3 | 1000 |
We’ll use a single integer to store all these settings together using bits.
Step 1: Start with All Settings OFF
settings = 0b0000 # all bits are OFF
print(bin(settings)) # '0b0'
Step 2: Turn ON Notifications and Dark Mode
NOTIFICATIONS = 0b0001
DARK_MODE = 0b0010
settings = settings | NOTIFICATIONS
settings = settings | DARK_MODE
print(bin(settings)) # Output: '0b11'
Now bit 0 and bit 1 are ON → binary is 0011
.
Step 3: Check if Location Access is ON
LOCATION = 0b0100
if settings & LOCATION:
print("Location access is ON")
else:
print("Location access is OFF")
Since we never turned it ON, the result will be:
Location access is OFF
Step 4: Turn OFF Dark Mode
settings = settings & ~DARK_MODE
print(bin(settings)) # Output: '0b1'
Now only Notifications are ON.
Step 5: Turn ON Auto-Update
AUTO_UPDATE = 0b1000
settings = settings | AUTO_UPDATE
print(bin(settings)) # Output: '0b1001'
So now, Notifications and Auto-Update are ON.
Final Recap:
You just built a mini feature switch system using:
|
to turn settings ON&
with~
to turn them OFF&
to check if a setting is ONbin()
to see what’s happening
This is how things like game settings, permissions, and device flags are handled in real projects.
Quick Recap Table
Operator | Name | Python Symbol | Example | Result |
---|---|---|---|---|
AND | Bitwise AND | & | 10 & 4 | 0 |
OR | Bitwise OR | ` | ` | `10 |
XOR | Bitwise XOR | ^ | 10 ^ 4 | 14 |
NOT | Bitwise NOT | ~ | ~10 | -11 |
Left | Left Shift | << | 10 << 2 | 40 |
Right | Right Shift | >> | 10 >> 2 | 2 |
Conclusion
Bitwise operators might look tricky at first — all those &
, |
, ^
, and ~
symbols can feel like secret codes. But once you understand what they actually do (just flipping or checking bits), it all starts to make sense.
In this post, we looked at:
- What each bitwise operator does — step by step
- How to use
bin()
to see what’s happening - How to use parentheses to keep your code clean
- and How to use masking to check, set, or clear bits
- And finally, how all of this works in a real example
These tools are especially useful when you’re working with low-level data, settings flags, or anything that needs fast, compact control.
Don’t worry if it doesn’t all click immediately — bitwise operations are something you get better at with a little practice. Try using them in small projects or write a few more examples on your own.
And if you ever get stuck, just use bin()
to peek under the hood. The bits won’t lie.
Quiz for practice on Bitwise Operators in Python
1: What will be the result of 5 & 3
in Python?
A. 7
B. 1
C. 0
D. 8
Correct Answer: B. 1
Explanation:
In binary:5 = 101
3 = 011
101 & 011 = 001
→ which is 1
2: How do you turn ON only bit 2 in a flag using bitwise operators?
A. flags = flags & 0b0100
B. flags = flags | 0b0100
C. flags = flags ^ 0b0100
D. flags = ~flags
Correct Answer: B. flags = flags | 0b0100
Explanation:
The |
(OR) operator turns ON bits. 0b0100
is bit 2.
3: What does ~
(bitwise NOT) do in Python?
A. It turns OFF all bits
B. It inverts each bit (0 becomes 1, 1 becomes 0)
C. It multiplies the number by -1
D. It reverses the number
Correct Answer: B
Explanation:
The ~
operator flips every bit. In Python, it also includes a two’s complement, so ~5
gives -6
.
4: If flags = 0b1101
, how do you check if bit 2 is ON?
A. flags & 0b0100
B. flags | 0b0100
C. flags ^ 0b0100
D. ~flags & 0b0100
Correct Answer: A. flags & 0b0100
Explanation:
Use &
to check a specific bit. If the result is not 0, the bit is ON.
5: What is the output of this code?
a = 10 # 0b1010
b = 4 # 0b0100
print(a ^ b)
A. 6
B. 14
C. 0
D. 12
Correct Answer: D. 14
Explanation:a = 1010
, b = 0100
1010 ^ 0100 = 1110
→ which is 14
External Resources
Python Official Documentation – Bitwise Operations
A straight-to-the-point section from Python’s official docs. Useful for quick reference on how each operator works.
Bitwise Tricks in Competitive Programming – HackerEarth Blog
Shows how bitwise operators are used in optimization, flag handling, and challenges. A good read if you’re interested in how bitwise logic is used in real-world logic puzzles and programming contests.
FAQs
Great question! Bitwise operators are handy when you want to store multiple ON/OFF states in just one number. It’s super efficient, especially for things like settings, permissions, or performance-critical tasks. Instead of having four separate True
/False
variables, you can handle them all with one integer using bits.
Use Python’s built-in bin()
function! It converts a number to its binary string, so you can actually see the 0s and 1s. For example:
print(bin(5)) # Output: ‘0b101’
It’s a great way to debug and understand what your bitwise code is doing.
Yes, but be careful. Python represents negative numbers using two’s complement, so the bits might look confusing at first. For example, ~5
gives -6
. If you’re doing bit-level work, it’s usually best to stick with non-negative integers unless you’re sure how negatives are handled in binary.