π’ Bit Manipulation: The Secret Language of Computers
The Story of Light Switches π‘
Imagine a row of 8 light switches on your wall. Each switch can be ON (1) or OFF (0). Thatβs exactly how computers store numbers! Instead of thinking about β42β or β7β, computers think in switchesβbits!
Every single thing your computer doesβplaying games, showing videos, loading websitesβhappens because tiny switches flip ON and OFF, millions of times per second.
Today, youβll learn to speak this secret switch language!
π§± Bit Manipulation Fundamentals
What is a Bit?
A bit is the smallest piece of information a computer understands.
- 0 = OFF (no electricity flowing)
- 1 = ON (electricity flowing)
Think of it like:
- A single light bulb π‘
- A yes/no question
- A coin flip (heads/tails)
What is a Byte?
A byte = 8 bits together
One byte looks like: 01001010
ββββββββ
8 switches!
Binary to Decimal Magic
Each switch position has a power value:
Position: 7 6 5 4 3 2 1 0
Value: 128 64 32 16 8 4 2 1
Example: What is 00001010 in decimal?
0Γ128 + 0Γ64 + 0Γ32 + 0Γ16 + 1Γ8 + 0Γ4 + 1Γ2 + 0Γ1
β β
8 + 2 = 10
So 00001010 = 10 in decimal!
β‘ Bitwise Operations
These are the magic wands that change our switches. There are 6 main operations.
1. AND (&) β Both Must Be ON
AND only gives 1 if BOTH switches are ON.
Light Switch Analogy:
Two switches control ONE bulb.
Both must be ON for light!
1 AND 1 = 1 β Both on β Light!
1 AND 0 = 0 β One off β Dark
0 AND 1 = 0 β One off β Dark
0 AND 0 = 0 β Both off β Dark
JavaScript Example:
let a = 5; // Binary: 0101
let b = 3; // Binary: 0011
let result = a & b; // Result: 0001 = 1
// Why?
// 0101 (5)
// & 0011 (3)
// ------
// 0001 (1)
2. OR (|) β At Least One ON
OR gives 1 if ANY switch is ON.
Light Switch Analogy:
Either switch can turn on the bulb!
1 OR 1 = 1 β At least one on
1 OR 0 = 1 β At least one on
0 OR 1 = 1 β At least one on
0 OR 0 = 0 β Both must be off
JavaScript Example:
let a = 5; // Binary: 0101
let b = 3; // Binary: 0011
let result = a | b; // Result: 0111 = 7
3. XOR (^) β Exactly One ON
XOR gives 1 only when the switches are DIFFERENT.
The "Disagreement" Operator:
Only light up when switches disagree!
1 XOR 1 = 0 Same β Dark
1 XOR 0 = 1 Different β Light!
0 XOR 1 = 1 Different β Light!
0 XOR 0 = 0 Same β Dark
JavaScript Example:
let a = 5; // Binary: 0101
let b = 3; // Binary: 0011
let result = a ^ b; // Result: 0110 = 6
4. NOT (~) β Flip All Switches
NOT flips every switch to its opposite.
let a = 5; // Binary: 00000101
let result = ~a; // Flips: 11111010 = -6
β οΈ In JavaScript,
~n = -(n+1)due to how negative numbers work!
5. Left Shift (<<) β Multiply Power!
Shifts all bits LEFT. Each shift doubles the number!
Imagine pushing all switches LEFT:
0101 << 1 β 1010
(5) (10)
5 Γ 2 = 10 β
JavaScript Example:
let a = 3; // Binary: 0011
let result = a << 2; // Shift 2: 1100 = 12
// 3 Γ 4 = 12 β (2Β² = 4)
6. Right Shift (>>) β Divide Power!
Shifts all bits RIGHT. Each shift halves the number!
1000 >> 1 β 0100
(8) (4)
8 Γ· 2 = 4 β
JavaScript Example:
let a = 16; // Binary: 10000
let result = a >> 2; // Shift 2: 00100 = 4
// 16 Γ· 4 = 4 β
π οΈ Bit Manipulation Techniques
These are your power tools for solving problems!
Technique 1: Check if Bit is Set
Question: Is the bit at position i turned ON?
function isBitSet(n, i) {
return (n & (1 << i)) !== 0;
}
// Example: Is bit 2 set in 5?
// 5 = 0101
// β Position 2 is 1 β YES!
isBitSet(5, 2); // true
Technique 2: Set a Bit (Turn ON)
function setBit(n, i) {
return n | (1 << i);
}
// Turn ON bit 1 in number 4
// 4 = 0100 β 0110 = 6
setBit(4, 1); // 6
Technique 3: Clear a Bit (Turn OFF)
function clearBit(n, i) {
return n & ~(1 << i);
}
// Turn OFF bit 2 in number 5
// 5 = 0101 β 0001 = 1
clearBit(5, 2); // 1
Technique 4: Toggle a Bit (Flip)
function toggleBit(n, i) {
return n ^ (1 << i);
}
// Flip bit 0 in number 4
// 4 = 0100 β 0101 = 5
toggleBit(4, 0); // 5
π Count Set Bits
Problem: How many switches are ON in a number?
Method 1: Loop Through Each Bit
function countSetBits(n) {
let count = 0;
while (n > 0) {
count += n & 1; // Check last bit
n = n >> 1; // Move to next bit
}
return count;
}
countSetBits(7); // 7 = 0111 β 3 bits
countSetBits(10); // 10 = 1010 β 2 bits
Method 2: Brian Kernighanβs Trick β‘
Magic idea: n & (n-1) removes the rightmost 1-bit!
function countSetBitsFast(n) {
let count = 0;
while (n > 0) {
n = n & (n - 1); // Remove last 1
count++;
}
return count;
}
// How it works with 7 (0111):
// Step 1: 0111 & 0110 = 0110 (count=1)
// Step 2: 0110 & 0101 = 0100 (count=2)
// Step 3: 0100 & 0011 = 0000 (count=3)
// Done! Answer: 3
β¨ Power of Two Check
Problem: Is this number a power of 2? (like 1, 2, 4, 8, 16β¦)
Secret: Powers of 2 have exactly ONE bit set!
1 = 0001 β One bit
2 = 0010 β One bit
4 = 0100 β One bit
8 = 1000 β One bit
6 = 0110 β Two bits
The One-Line Magic:
function isPowerOfTwo(n) {
return n > 0 && (n & (n - 1)) === 0;
}
// Why does this work?
// 8 = 1000
// 8 - 1 = 0111
// 1000 & 0111 = 0000 β Power of 2!
// 6 = 0110
// 6 - 1 = 0101
// 0110 & 0101 = 0100 β 0 β Not power of 2
π Single Number XOR
Problem: In an array where every number appears twice except one, find the unique number!
XOR Magic Properties:
a ^ a = 0 (same numbers cancel out!)
a ^ 0 = a (zero doesn't change anything)
Solution:
function singleNumber(nums) {
let result = 0;
for (let num of nums) {
result ^= num;
}
return result;
}
// Example: [4, 1, 2, 1, 2]
// 0 ^ 4 = 4
// 4 ^ 1 = 5
// 5 ^ 2 = 7
// 7 ^ 1 = 6 (1 cancelled!)
// 6 ^ 2 = 4 (2 cancelled!)
// Answer: 4 β
π¬ Single Number II
Problem: Every number appears THREE times except one. Find the unique one!
Idea: Count bits at each position. If count % 3 β 0, that bit belongs to our answer!
function singleNumberII(nums) {
let result = 0;
for (let i = 0; i < 32; i++) {
let bitSum = 0;
// Count 1s at position i
for (let num of nums) {
bitSum += (num >> i) & 1;
}
// If not divisible by 3, it's our number's bit
if (bitSum % 3 !== 0) {
result |= (1 << i);
}
}
return result;
}
// Example: [2, 2, 3, 2]
// Bit 0: 0+0+1+0 = 1 β 1 % 3 = 1 β Set bit 0
// Bit 1: 1+1+1+1 = 4 β 4 % 3 = 1 β Set bit 1
// Result: 11 = 3 β
π― Missing Number using XOR
Problem: Array has numbers 0 to n, but ONE is missing. Find it!
Clever Idea: XOR all numbers AND all indices. Pairs cancel, leaving the missing one!
function missingNumber(nums) {
let result = nums.length; // Start with n
for (let i = 0; i < nums.length; i++) {
result ^= i ^ nums[i];
}
return result;
}
// Example: [3, 0, 1] (missing 2)
// result = 3
// i=0: 3 ^ 0 ^ 3 = 0
// i=1: 0 ^ 1 ^ 0 = 1
// i=2: 1 ^ 2 ^ 1 = 2 β Missing!
Why this works:
XOR everything:
(0 ^ 1 ^ 2 ^ 3) ^ (3 ^ 0 ^ 1)
β expected β actual
= 0^0 ^ 1^1 ^ 2 ^ 3^3
= 0 ^ 0 ^ 2 ^ 0
= 2 β The missing number!
π Summary: Your Bit Manipulation Toolkit
graph LR A["Bit Operations"] --> B["AND &"] A --> C["OR |"] A --> D["XOR ^"] A --> E["NOT ~"] A --> F["Left Shift <<"] A --> G["Right Shift >>"] H["Common Tricks"] --> I["Check Bit"] H --> J["Set Bit"] H --> K["Clear Bit"] H --> L["Toggle Bit"] M["Classic Problems"] --> N["Count Set Bits"] M --> O["Power of Two"] M --> P["Single Number"] M --> Q["Missing Number"]
π Quick Reference Card
| Operation | Symbol | What It Does |
|---|---|---|
| AND | & |
Both must be 1 |
| OR | | |
At least one is 1 |
| XOR | ^ |
Exactly one is 1 |
| NOT | ~ |
Flip all bits |
| Left Shift | << |
Multiply by 2βΏ |
| Right Shift | >> |
Divide by 2βΏ |
| Trick | Formula |
|---|---|
| Check bit i | n & (1 << i) |
| Set bit i | n | (1 << i) |
| Clear bit i | n & ~(1 << i) |
| Toggle bit i | n ^ (1 << i) |
| Is power of 2? | n & (n-1) === 0 |
| Remove rightmost 1 | n & (n-1) |
| Get rightmost 1 | n & (-n) |
You did it! π You now speak the secret language of computers. Every time you toggle a bit, youβre talking directly to the machineβs heartβtiny switches flipping on and off, creating the digital world we live in.
Keep practicing, and these operations will become second nature!
