Bitwise operators are a fundamental aspect of programming that allow you to manipulate individual bits within a binary number. Understanding these operators will give you the ability to perform low-level operations on data, such as setting, clearing, and testing specific bits in a number. This knowledge can be essential when dealing with system programming, cryptography, and other advanced topics.
In this lesson, we'll explore the core concepts of bitwise operators, delve into practical examples, learn common issues, and discuss best practices for using them effectively.
Bitwise AND (&
): Performs a bit-by-bit comparison between two numbers and sets the corresponding bits to 1 if both bits are 1; otherwise, it sets the resulting bit to 0.
Example: 5 & 3 = 1
(Binary representation: 101
AND 011
equals 001
)
Bitwise OR (|
): Performs a bit-by-bit comparison between two numbers and sets the corresponding bits to 1 if at least one of the bits is 1; otherwise, it sets the resulting bit to 0.
Example: 5 | 3 = 7
(Binary representation: 101
OR 011
equals 111
)
Bitwise XOR (^
): Performs a bit-by-bit comparison between two numbers and sets the corresponding bits to 1 if exactly one of the bits is 1; otherwise, it sets the resulting bit to 0.
Example: 5 ^ 3 = 6
(Binary representation: 101
XOR 011
equals 110
)
Bitwise NOT/Inversion (~
): Flips all bits in a number, changing 0s to 1s and 1s to 0s.
Example: ~5 = -6
(Binary representation: 101
becomes 1101010
)
Bitwise left shift (<<
): Shifts the bits of a number to the left by the specified amount, filling the vacated bits with zeros.
Example: 5 << 2 = 20
(Shift left by 2 places: 101
becomes 1010000
)
Bitwise right shift (>>
): Shifts the bits of a number to the right by the specified amount, filling the vacated bits with zeros or signing bits if the number is negative.
Example: 5 >> 2 = 1
(Shift right by 2 places: 101
becomes 001
)
number = 0b0101 # Binary representation of the number 5
set_bit_4 = number | (1 << 3) # Set the fourth bit from the right (counting from 0)
clear_bit_2 = set_bit_4 & ~(1 << 1) # Clear the second bit from the right
result = clear_bit_2 >> 2 # Shift the result to the right by 2 places for easier viewing
print(f"{result:04b}") # Output: 0001 (Binary representation of the number 1)
num1 = 5
num2 = 3
xor_result = num1 ^ num2
not_result = ~xor_result
print(f"Numbers are the same if result is {not_result=}") # Output: Numbers are the same if result is 0
What causes it: Attempting to use a bitwise operator without defining it beforehand.
unknown_operator & some_number # This will trigger a NameError
Solution:
from operator import bitwise_and # Or any other bitwise operator you wish to use
bitwise_and(some_number, another_number)
Why it happens: Python doesn't recognize the operator because it hasn't been defined in the current scope.
How to prevent it: Import the specific bitwise operator from the operator
module or define it locally if you know exactly what you're doing.
What causes it: Trying to perform a bitwise operation on non-integer types, such as strings or floats.
string = "101"
bitwise_and(int(string), some_number) # This will trigger a TypeError
Solution:
number = int(string, base=2) # Convert the binary string to an integer before performing bitwise operations
Why it happens: Python expects integers for bitwise operations, so attempting to perform them on other types will result in a TypeError.
How to prevent it: Ensure that all operands are integers before performing bitwise operations.
What causes it: Attempting to shift a number by an invalid amount (negative or greater than the number of bits in the binary representation).
bitwise_right_shift(number, -1) # This will trigger a ValueError
Solution:
bitwise_right_shift(number, max(0, number.bit_length() - 1))
Why it happens: Python expects a non-negative integer for the shift amount, so attempting to shift by a negative or large value will result in a ValueError.
How to prevent it: Ensure that the shift amount is a non-negative integer and doesn't exceed the number of bits in the binary representation of the number.
What causes it: Shifting a number beyond its maximum possible bit length (e.g., shifting a 32-bit integer by more than 31).
number = 2**31 - 1 # Maximum positive 32-bit integer
shifted_number = number >> 32 # This will trigger an OverflowError
Solution:
if shift_amount > number.bit_length():
print("Overflow error: Cannot shift beyond the maximum bit length.")
else:
shifted_number = number >> shift_amount
Why it happens: Attempting to shift a number by more bits than its binary representation can hold will result in an OverflowError.
How to prevent it: Ensure that the shift amount is less than or equal to the number's bit length.
operator
module for convenience when defining specific bitwise operators.