Expert: advanced patterns and interviews · Tries, union-find and bit manipulation · topic 50 of 61 · 35 min
Bits: AND, OR, XOR and shifts
Explanation
Numbers are bits underneath
Computers store integers in binary, base 2. Each position is a bit, and bit i is worth 2 to the power i. Bit 0 is the rightmost one. So 13 is 8 + 4 + 1, which is 1101 in binary. In Python, bin(13) gives '0b1101', int("1101", 2) gives 13, and f"{13:08b}" gives '00001101', padded to 8 digits.
The operators
| Operator | Name | Rule for each bit | Example |
|---|---|---|---|
| a & b | AND | 1 only if both bits are 1 | 12 & 10 = 8 (1100 & 1010 = 1000) |
| a | b | OR | 1 if at least one bit is 1 | 12 | 10 = 14 (1110) |
| a ^ b | XOR | 1 if the bits are different | 12 ^ 10 = 6 (0110) |
| ~a | NOT | flip every bit | ~12 = −13 in Python |
| a << k | left shift | move bits k places left (× 2ᵏ) | 3 << 2 = 12 |
| a >> k | right shift | move bits k places right (÷ 2ᵏ, rounded down) | 13 >> 1 = 6 |
Check, set, clear and toggle one bit
A mask is a number with 1s only in the positions you care about. 1 << i is a mask with only bit i set. Combine it with the right operator:
n = 0b1010 # 10
print((n >> 1) & 1) # check bit 1 Output: 1
print(n | (1 << 0)) # set bit 0 Output: 11
print(n & ~(1 << 3)) # clear bit 3 Output: 2
print(n ^ (1 << 2)) # toggle bit 2 Output: 14The n & (n − 1) trick
Subtracting 1 from n flips its lowest 1 bit to 0 and turns all the 0s below it into 1s. AND-ing with n then removes exactly that lowest 1 bit. For 12 = 1100, 11 = 1011, and 12 & 11 = 1000 = 8.
A power of two (1, 2, 4, 8…) has exactly one 1 bit, so removing it leaves 0. The test is n > 0 and n & (n − 1) == 0; the n > 0 part rules out 0 and negative numbers. A related trick, n & −n, keeps ONLY the lowest 1 bit: 12 & −12 is 4.
Counting set bits
The number of 1 bits is called the popcount (population count). Three ways in Python: bin(n).count("1"); n.bit_count(), available since Python 3.10; or Brian Kernighan's method, which repeats n &= n − 1 until n is 0 and counts the steps. Kernighan's loop runs once per 1 bit, not once per bit, which interviewers like.
def count_bits(n):
count = 0
while n:
n &= n - 1
count += 1
return count
print(count_bits(13), bin(13).count("1"), (13).bit_count()) # Output: 3 3 3Warning: Python integers are unbounded
In Java, C++ and similar languages, an int has a fixed width such as 32 bits, and negative numbers use two's complement. Python integers grow as large as needed. They behave as if a negative number had infinitely many 1 bits on the left. This changes several things you may have learnt elsewhere.
print(~5) # Output: -6 (~x is always -x - 1)
print(bin(-5)) # Output: -0b101 (a sign, not two's complement)
print(-1 >> 1) # Output: -1 (shifting a negative never reaches 0)
print(-5 & 0xFFFFFFFF) # Output: 4294967291 (the 32-bit pattern of -5)JavaScript goes the other way: its bitwise operators first convert numbers to 32-bit signed integers. So (2 ** 31) | 0 is −2147483648, and >>> is an extra "unsigned" right shift that fills with 0s: −1 >>> 0 is 4294967295.
Real use: permission flags
Many systems pack several yes/no settings into one number. Linux file permissions are the famous example: read = 4 (100), write = 2 (010), execute = 1 (001). chmod 7 means 111, all three; 6 is 110, read and write; 5 is 101, read and execute. chmod 754 gives the owner 7 (rwx), the group 5 (r-x) and everyone else 4 (r--). To test "can write?", check perms & 2 != 0. Feature flags in apps and settings in games are often stored the same way.
Common mistakes
- Writing 2 ^ 3 for "two to the power three". In Python and JavaScript, ^ is XOR, so 2 ^ 3 is 1. Fix: 2 ** 3, or 1 << 3.
- Forgetting brackets in JavaScript, Java or C: there, n & 1 == 0 means n & (1 == 0). Python happens to group it as (n & 1) == 0, but brackets make every language safe.
- Testing a power of two without n > 0, so 0 passes. Fix: n > 0 and n & (n − 1) == 0.
- Expecting ~x or bin(x) to show 32-bit patterns in Python. Fix: mask with & 0xFFFFFFFF.
- Off by one with bit positions: the rightmost bit is bit 0, not bit 1.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Bits: AND, OR, XOR and shifts · 1/8
This lesson is about bits: the zeros and ones inside every integer, and the operators that work on them directly.
Prefer a video by a teacher? Find free videos on “bit manipulation basics and or xor shift tricks interview python” on YouTube ↗
In real life: Permission flags in an app
A document-sharing app can store what each user may do as one small number instead of several true/false columns: view = 4, comment = 2, edit = 1, just like Linux file permissions. Giving a permission is an OR, taking it away is an AND with the inverted mask, and checking it is an AND. One number per user is quick to store and compare.
VIEW, COMMENT, EDIT = 4, 2, 1
perms = VIEW | COMMENT # 6 = 110
print(perms, bool(perms & EDIT))
perms |= EDIT # give edit: 7 = 111
print(perms, f"{perms:03b}")
perms &= ~COMMENT # take away comment: 5 = 101
print(perms, bool(perms & COMMENT))Practice (0/4 done)
Write is_power_of_two(n) that returns True if n is a power of two (1, 2, 4, 8, …) and False otherwise. 0 and negative numbers are never powers of two. Use the n & (n − 1) trick, no loops. Example: is_power_of_two(16) returns True and is_power_of_two(6) returns False.
Write count_bits(n) that returns the number of 1 bits in the binary form of n (n ≥ 0). Use Brian Kernighan's method: repeat n &= n − 1 and count the steps. Python integers can be very large, and your function must work for them too. Example: count_bits(13) returns 3, because 13 is 1101.
Write four functions for n ≥ 0 and bit position i ≥ 0 (bit 0 is the rightmost): get_bit(n, i) returns 1 if bit i of n is set, else 0; set_bit(n, i) returns n with bit i set to 1; clear_bit(n, i) returns n with bit i set to 0; toggle_bit(n, i) returns n with bit i flipped. Use shifts and masks. Example: 10 is 1010, so get_bit(10, 1) is 1 and set_bit(10, 0) is 11.
Write countSetBits(n) in JavaScript for a whole number n with 0 ≤ n ≤ 4294967295 (any 32-bit unsigned value). Return how many 1 bits it has. JavaScript bitwise operators work on 32-bit SIGNED integers, so for values of 2³¹ and above use >>> (unsigned right shift), not >>: with >>, the number turns negative and a loop like while (n !== 0) may never end. Example: countSetBits(11) returns 3.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Bit tricks in interviewsTries, union-find and bit manipulation · same module
- Union-find (disjoint set union)Tries, union-find and bit manipulation · same module
- Bitwise operatorsC Programming (from zero to systems) · Bits, undefined behaviour and safety
- Masks and flagsC Programming (from zero to systems) · Bits, undefined behaviour and safety
- Binary and decimal for networkingComputer Networking (CCNA level) · IPv4 addressing
- Subnet masks, prefix length and wildcard masksComputer Networking (CCNA level) · IPv4 addressing
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What is 12 & 10?
Answer: 8
1100 AND 1010 keeps only the bits set in both: 1000 = 8.
What is 13 ^ 6?
Answer: 11
1101 XOR 0110 = 1011 = 11: bits that differ become 1.
What does n & (n − 1) do?
Answer: Removes the lowest 1 bit of n
n − 1 flips the lowest 1 bit and the 0s below it, so the AND clears that bit.
What does ~5 give in Python?
Answer: -6
For Python ints, ~x is always −x − 1.
A file has permission 6 for its owner. What may the owner do?
Answer: Read and write
6 = 110: read (4) and write (2), no execute (1).
Why does "while n: n >>= 1" never end for n = −1 in Python?
Answer: -1 >> 1 is still -1
Right-shifting a negative Python int rounds down, so −1 stays −1 forever.
Why use unsigned types for bit manipulation?Related
Answer: Shifts and overflow are well defined for unsigned types
Signed shifts have implementation-defined or undefined cases.
From Bitwise operators
Which expression clears bit 5 of x?Related
Why might XOR be preferred over the sum formula for "missing number" in Java or C++?Related
Answer: A big sum can overflow a fixed-size int; XOR cannot
n(n + 1)/2 can exceed 32 bits; XOR results never grow beyond the inputs' width.
How many bits are in one octet?Related
Answer: 8
An octet is 8 bits. An IPv4 address has 4 octets, so 32 bits.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 1 more topic in “Tries, union-find and bit manipulation” before its exam: Bit tricks in interviews.
- Module 10 exam: Tries, union-find and bits · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Dynamic programming. 61 topics left in the course before the final exam.