Unit 1 · Algorithms · Lesson 21 of 24
Bit manipulation
Builds on
Step 1: Learn the ideas
- Binary representation and fixed width
- Two's complement
- AND, OR, XOR, NOT and shifts
- Masks: test, set, clear, toggle
- Lowest-set-bit tricks and population count
- XOR cancellation and per-bit counting
- Subsets and submasks as integers; bitmask DP
- Language-specific shift, sign and overflow rules
Why it matters
Bit manipulation is a smaller interview topic than graphs or DP, but it is everyday material in low-level and systems work (flags and permissions, packed formats, hashing, network masks, checksums) and a tool inside other algorithms (subset enumeration, bitmask DP, Bloom filters). Interviewers mostly check that you read and write mask expressions correctly and know where your language's integer model differs from the textbook one.
Core ideas
Masks. For bit k: test with (x >> k) & 1, set with x | (1 << k), clear with x & ~(1 << k), toggle with x ^ (1 << k). The low k bits are (1 << k) - 1.
Two's complement. In w-bit two's complement the top bit has weight -2^(w-1), so -x == ~x + 1. Consequences: x & -x keeps only the lowest set bit, x & (x - 1) clears it, and x > 0 with (x & (x - 1)) == 0 means x is a power of two. For non-negative x, repeating x &= x - 1 counts set bits in as many steps as there are ones; prefer built-ins when allowed (int.bit_count in Python 3.10+, Integer.bitCount in Java, std::popcount in C++20).
XOR. XOR is associative and commutative, x ^ x is 0 and x ^ 0 is x, so XOR-ing a collection cancels every value that appears an even number of times. When values repeat three times, count each bit position modulo 3 instead.
Subsets as integers. For n up to about 20, iterate masks from 0 to 2^n - 1 and include element i when bit i is set; a DP over subsets typically costs around O(2^n · n). The submasks of a mask can be walked with sub = (sub - 1) & mask; over all masks this totals O(3^n).
Shifts. A left shift by k multiplies by 2^k while nothing overflows. Right-shifting a negative number is arithmetic (sign-extending) in Java's >>, in Python and, since C++20, in C++; Java's >>> fills with zeros. Java masks shift distances to the low five bits for int, so 1 << 32 is 1, not 0.
Language pitfalls.
- Python integers are unbounded:
~xis -x - 1, negatives behave as if they had infinitely many leading ones, and nothing overflows. To emulate 32-bit arithmetic, mask with& 0xFFFFFFFFand convert back to signed when bit 31 is set. A loop that adds without + by propagating carries can run forever on inputs such as -1 and 1 unless you mask. - Java has fixed-width int and long with silent wraparound; use
1L << kfor bits above 31. - In C and C++, shifting by a negative amount or by at least the bit width is undefined behavior, as is signed overflow. Left-shifting a negative value is undefined in C and was until C++20, so use unsigned types for bit work.
- Precedence: in C and C++, == binds tighter than &, ^ and |, so
x & 1 == 0silently meansx & (1 == 0); Java rejects it at compile time, and Python reads it as intended. Parenthesize every bitwise subexpression.
Common misconceptions
- "x >> 1 equals x / 2 for every integer." For negative odd numbers, the arithmetic shift rounds toward negative infinity while Java and C division rounds toward zero:
-3 >> 1is -2 but-3 / 2is -1. - "Bit tricks are always faster." Compilers already turn multiplication and division by constants into shifts where that is valid; readable code with built-ins usually wins.
- "
~5is a large positive number." In Python it is -6, because Python integers have no fixed width. - "1 << 31 is a large positive int in Java." It is Integer.MIN_VALUE; use long when you need 32 or more bits.
How to approach it
State the bit width and signedness before writing anything. Name your masks, test with 0, 1, a power of two, -1 and the most negative value, and compare against a plain arithmetic version on small random inputs. For low-level roles, be ready to explain what your language does on overflow and on shifts by large or negative amounts.
Suggested order
- 1Read CSES handbook Ch. 10 (Bit manipulation), the sections on bit representation, bit operations and representing sets.
- 2Read the Python documentation on bitwise operations on integer types, or JLS 15.19 (Shift Operators) if you interview in Java, and note how negative numbers and shift distances are defined.
- 3Write and test helpers for test, set, clear, toggle and lowest set bit on 0, 1, -1 and the most negative 32-bit value.
- 4Solve Single Number, Number of 1 Bits and Power of Two, then Counting Bits using the relation between x and x & (x - 1).
- 5Solve Missing Number, Reverse Bits and Single Number II; in Python, handle negative results explicitly.
- 6Solve Sum of Two Integers and Bitwise AND of Numbers Range, then browse Bit Twiddling Hacks for patterns, testing each trick you adopt against a brute-force version.
Step 2: Check off what you can do
Tap each one you can genuinely do or explain. Each earns 10 XP.
Step 3: Go deeper
Competitive Programmer’s HandbookStart here
CSESSection: Ch. 10: Bit manipulation
Two's complement, bit operations, sets as bitmasks and bitmask DP in a few compact pages.
Open(opens in a new tab)Link responded, 5 Oct 2026Python documentation: bitwise operations on integer typesStart here
Python Software FoundationSection: Bitwise Operations on Integer Types
Exact semantics of Python bitwise operators on unbounded integers, including negative numbers and shift counts.
Open(opens in a new tab)Link responded, 5 Oct 2026Java Language Specification (Java SE 25), 15.19 Shift Operators
OracleSection: 15.19 Shift Operators
Normative rules for <<, >> and >>> in Java, including masking of shift distances; read if Java is your interview language.
Open(opens in a new tab)Link responded, 5 Oct 2026Bit Twiddling Hacks
Stanford University (author page)Reference catalogue of bit tricks for C; useful for patterns, but verify each one and note its fixed-width assumptions.
Open(opens in a new tab)Link responded, 5 Oct 2026
Step 4: Practice
Test every bitwise solution on 0, 1, -1 and the extreme values of your integer type, and compare it with a simple arithmetic version on random small inputs. In Python, decide up front whether you are emulating 32-bit behavior and mask consistently. Keep the last three for review rotation.
- Single NumberLeetCode(opens in a new tab)Not attemptedLeetCode
- Number of 1 BitsLeetCode(opens in a new tab)Not attemptedLeetCode
- Power of TwoLeetCode(opens in a new tab)Not attemptedLeetCode
- Counting BitsLeetCode(opens in a new tab)Not attemptedLeetCode
- Missing NumberLeetCode(opens in a new tab)Not attemptedLeetCode
- Reverse BitsLeetCode(opens in a new tab)Not attemptedLeetCode
- Single Number IILeetCode(opens in a new tab)Not attemptedLeetCode
- Sum of Two IntegersLeetCode(opens in a new tab)Not attemptedLeetCode
- Bitwise AND of Numbers RangeLeetCode(opens in a new tab)Not attemptedLeetCode
Record attempts on each problem’s page (+15 XP, +10 more when solved on your own).
Step 5: Test yourself
Answer each one out loud or on paper before you finish the lesson.
- Question 1Why does x & (x - 1) clear exactly the lowest set bit?
- Question 2What is ~x in Python, and why does it differ from a fixed-width language?
- Question 3What is the difference between >> and >>> in Java?
- Question 4How do you enumerate all submasks of a mask, and what is the total cost over all masks?
- Question 5Up to roughly which n is iterating over all subsets feasible?
- Question 6Why can -3 >> 1 and -3 / 2 give different results?
You’re done when you can
- Write test, set, clear, toggle and lowest-set-bit expressions from memory and explain each in one sentence.
- Explain two's complement and why x & -x isolates the lowest set bit, without notes.
- Solve Sum of Two Integers or Single Number II in your interview language with correct handling of negative numbers.
- State how your interview language handles right shifts of negative numbers and shifts by at least the bit width.


