Bitwise operators are special symbols that perform operations on integers at the level of their individual bits (the 1s and 0s of their binary representation). They are powerful for low-level data manipulation, setting flags, and performing highly efficient calculations.
& (Bitwise AND)
This operator compares two numbers bit by bit. If both corresponding bits are 1, the resulting bit is 1; otherwise, it's 0.
Shell
# Basic: Simple AND operation
# 5 (0101) & 3 (0011) = 1 (0001)
>>> 5 & 3
1
# Intermediate: Checking if a number is even or odd
# An odd number's last bit is always 1.
# num & 1 will be 1 if odd, 0 if even.
>>> 17 & 1
1
>>> 18 & 1
0
# Advanced: Masking out bits
# Get the lower 4 bits of a number (e.g., a byte).
# 0b1111 is the mask for the lower 4 bits.
>>> 170 # Binary: 10101010
>>> 170 & 0b1111 # 10101010 & 00001111 = 00001010
10
| (Bitwise OR)
This operator compares two numbers bit by bit. If at least one of the corresponding bits is 1, the resulting bit is 1; otherwise, it's 0.
Shell
# Basic: Simple OR operation
# 5 (0101) | 3 (0011) = 7 (0111)
>>> 5 | 3
7
# Intermediate: Setting a specific bit to 1
# Let's turn on the 4th bit (value 8, binary 1000).
>>> num = 5 # Binary: 0101
>>> num | 0b1000 # 0101 | 1000 = 1101
13
# Advanced: Combining permission flags
>>> READ_PERMISSION = 4 # 0100
>>> WRITE_PERMISSION = 2 # 0010
>>> user_permissions = READ_PERMISSION | WRITE_PERMISSION # 0100 | 0010 = 0110
>>> user_permissions
6
^ (Bitwise XOR - Exclusive OR)
This operator compares two numbers bit by bit. If the corresponding bits are different, the resulting bit is 1; otherwise, it's 0.
Shell
# Basic: Simple XOR operation
# 5 (0101) ^ 3 (0011) = 6 (0110)
>>> 5 ^ 3
6
# Intermediate: Toggling a specific bit
# Toggling the 2nd bit (value 2, binary 0010) on and off.
>>> num = 5 # Binary: 0101
>>> num ^= 2 # 0101 ^ 0010 = 0111 (7)
>>> num
7
>>> num ^= 2 # 0111 ^ 0010 = 0101 (5)
>>> num
5
# Advanced: Swapping two variables without a temporary variable
>>> a = 10
>>> b = 20
>>> a ^= b
>>> b ^= a
>>> a ^= b
>>> print(f"a={a}, b={b}")
a=20, b=10
~ (Bitwise NOT - Complement)
This unary operator inverts all the bits of a number (0s become 1s and 1s become 0s). In Python, for a number x, the result is always -(x + 1).
Shell
# Basic: Simple NOT operation
>>> ~5
-6
# Intermediate: Creating a mask to turn OFF a bit
# Let's turn off the 2nd bit (value 2) from 7 (0111).
>>> num = 7
>>> mask = ~2 # ~0010 becomes ...11111101
>>> num & mask # 0111 & ...1101 = 0101 (5)
5
# Advanced: Checking for -1
# In some low-level programming, -1 is an error flag.
# ~(-1) is 0.
>>> error_code = -1
>>> if ~error_code == 0:
... print("An error occurred.")
...
An error occurred.
<< (Left Shift)
This operator shifts the bits of a number to the left by a specified number of places, adding zeros to the right.
Shell
# Basic: Simple left shift
# 5 (0101) << 1 = 10 (1010)
>>> 5 << 1
10
# Intermediate: Fast multiplication by powers of 2
# Multiplying by 8 (2**3) is the same as shifting left by 3.
>>> 10 << 3
80
>>> 10 * 8
80
# Advanced: Creating bitmasks dynamically
# Create a mask for the 5th bit.
>>> 1 << 5 # 00000001 << 5 = 00100000
32
>> (Right Shift)
This operator shifts the bits of a number to the right by a specified number of places, discarding the rightmost bits.
Power Boosting with Bitwise Operator Overloading
Aug 28, 12:04 AM
Shell
# Basic: Simple right shift
# 10 (1010) >> 1 = 5 (0101)
>>> 10 >> 1
5
# Intermediate: Fast floor division by powers of 2
# Floor dividing by 4 (2**2) is the same as shifting right by 2.
>>> 80 >> 2
20
>>> 80 // 4
20
# Advanced: Extracting the value of a specific bit
# Get the value of the 3rd bit (value 4) of the number 13 (1101).
>>> num = 13
>>> (num >> 2) & 1 # 1101 >> 2 = 0011. Then 0011 & 0001 = 1
1
Operator Overloading example:
# --- 1. Define the Custom Class: PermissionSet ---
# This class uses a single integer to store a combination of permission flags.
class PermissionSet:
# Define permission flags as class attributes
READ = 4 # 0100
WRITE = 2 # 0010
EXECUTE = 1 # 0001
ALL = 7 # 0111
def __init__(self, flags=0):
"""Initializes the permission set with an integer."""
self.flags = int(flags)
def __repr__(self):
"""Provides a readable representation of the permissions."""
perms = []
if self.flags & self.READ: perms.append("READ")
if self.flags & self.WRITE: perms.append("WRITE")
if self.flags & self.EXECUTE: perms.append("EXECUTE")
return f"PermissionSet({self.flags}, {perms})"
# --- Bitwise Operator Overloads ---
def __and__(self, other):
"""Defines '&': Intersection of permissions."""
if isinstance(other, PermissionSet):
return PermissionSet(self.flags & other.flags)
return NotImplemented
def __or__(self, other):
"""Defines '|': Union of permissions."""
if isinstance(other, PermissionSet):
return PermissionSet(self.flags | other.flags)
return NotImplemented
def __xor__(self, other):
"""Defines '^': Permissions in one set but not both."""
if isinstance(other, PermissionSet):
return PermissionSet(self.flags ^ other.flags)
return NotImplemented
def __invert__(self):
"""Defines '~': Opposite permissions within the defined universe (ALL)."""
# We XOR with ALL to get the inverse within our defined permission set.
return PermissionSet(self.flags ^ self.ALL)
def __lshift__(self, bits):
"""Defines '<<': Left shift on the internal flags."""
if isinstance(bits, int):
return PermissionSet(self.flags << bits)
return NotImplemented
def __rshift__(self, bits):
"""Defines '>>': Right shift on the internal flags."""
if isinstance(bits, int):
return PermissionSet(self.flags >> bits)
return NotImplemented
# --- 2. Demonstration ---
# Create permission sets for different roles
admin_perms = PermissionSet(PermissionSet.READ | PermissionSet.WRITE | PermissionSet.EXECUTE)
user_perms = PermissionSet(PermissionSet.READ)
editor_perms = PermissionSet(PermissionSet.READ | PermissionSet.WRITE)
print(f"Admin: {admin_perms}")
print(f"User: {user_perms}")
print(f"Editor:{editor_perms}")
print("\n--- Using Overloaded Operators ---")
# What permissions do an Editor AND a User have in common?
common_perms = editor_perms & user_perms
print(f"Editor & User: {common_perms}")
# What is the full set of permissions for an Editor OR a User?
union_perms = editor_perms | user_perms
print(f"Editor | User: {union_perms}")
# What permissions does an Admin have that an Editor doesn't?
exclusive_perms = admin_perms ^ editor_perms
print(f"Admin ^ Editor: {exclusive_perms}")
# What permissions does a User NOT have?
inverted_user_perms = ~user_perms
print(f"~User: {inverted_user_perms}")