Understanding Bits and Binary
A bit (binary digit) is the fundamental unit of information in computing. It can hold one of two values: 0 or 1. When JavaScript performs bitwise operations, it converts numbers to 32-bit signed integers.
Binary Representation
Here's how decimal numbers are represented in binary:
Decimal 5 = Binary 00000000000000000000000000000101
Decimal 10 = Binary 00000000000000000000000000001010
Decimal -1 = Binary 11111111111111111111111111111111
Note: JavaScript uses Two's Complement for negative numbers.
Complete Bitwise Operators Reference
| Operator | Symbol | Description | Example | Result |
|---|---|---|---|---|
| AND | & |
Returns 1 if both bits are 1 | 5 & 3 |
1 |
| OR | | |
Returns 1 if either bit is 1 | 5 | 3 |
7 |
| XOR | ^ |
Returns 1 if bits are different | 5 ^ 3 |
6 |
| NOT | ~ |
Inverts all bits | ~5 |
-6 |
| Left Shift | << |
Shifts bits left, fills with 0s | 5 << 1 |
10 |
| Right Shift | >> |
Shifts bits right, preserves sign | 5 >> 1 |
2 |
| Zero-fill Right Shift | >>> |
Shifts bits right, fills with 0s | -5 >>> 1 |
2147483645 |
Detailed Examples with Visual Breakdown
Bitwise AND (&)
The AND operator compares each bit and returns 1 only if both bits are 1.
// Example: 12 & 10
12 in binary: 1100
10 in binary: 1010
----
Result: 1000 = 8
console.log(12 & 10); // Output: 8
Use Case: Checking if a number is even: num & 1 === 0
Bitwise OR (|)
The OR operator returns 1 if at least one bit is 1.
// Example: 12 | 10
12 in binary: 1100
10 in binary: 1010
----
Result: 1110 = 14
console.log(12 | 10); // Output: 14
Use Case: Setting specific bits in flags or permissions.
Bitwise XOR (^)
XOR returns 1 when bits are different, 0 when they're the same.
// Example: 12 ^ 10
12 in binary: 1100
10 in binary: 1010
----
Result: 0110 = 6
console.log(12 ^ 10); // Output: 6
// XOR Trick: Swapping variables without temp
let a = 5, b = 3;
a = a ^ b; // a = 5 ^ 3 = 6
b = a ^ b; // b = 6 ^ 3 = 5
a = a ^ b; // a = 6 ^ 5 = 3
console.log(a, b); // Output: 3, 5
Bitwise NOT (~)
NOT inverts all bits. Due to Two's Complement, ~n equals -(n+1).
// Example: ~5
5 in binary: 00000000000000000000000000000101
~5 in binary: 11111111111111111111111111111010 = -6
console.log(~5); // Output: -6
console.log(~-1); // Output: 0
// Quick trick: ~n === -(n+1)
console.log(~10 === -11); // true
Left Shift (<<)
Shifts bits to the left, effectively multiplying by 2^n.
// Example: 5 << 2
5 in binary: 101
5 << 2: 10100 = 20
console.log(5 << 2); // Output: 20
console.log(3 << 4); // Output: 48 (3 * 2^4)
// Fast multiplication by powers of 2
console.log(7 << 3); // 7 * 8 = 56
Right Shift (>>)
Shifts bits right while preserving the sign bit.
// Example: 20 >> 2
20 in binary: 10100
20 >> 2: 101 = 5
console.log(20 >> 2); // Output: 5
console.log(-20 >> 2); // Output: -5 (sign preserved)
// Fast division by powers of 2 (floor division)
console.log(15 >> 1); // 15 / 2 = 7 (floor)
Interactive Bitwise Calculator
🧮 Try Bitwise Operations
Real-World Applications
🔐 Permission Systems
Many systems use bitwise operations for managing user permissions efficiently.
// Permission flags
const PERMISSIONS = {
READ: 1, // 001
WRITE: 2, // 010
EXECUTE: 4 // 100
};
// Grant multiple permissions
let userPerms = PERMISSIONS.READ | PERMISSIONS.WRITE;
// Check if user has specific permission
function hasPermission(userPerms, permission) {
return (userPerms & permission) === permission;
}
console.log(hasPermission(userPerms, PERMISSIONS.READ)); // true
console.log(hasPermission(userPerms, PERMISSIONS.EXECUTE)); // false
🎨 Color Manipulation
RGB colors are often stored as single integers and manipulated with bitwise operations.
// Extract RGB components from hex color
function extractRGB(color) {
const r = (color >> 16) & 0xFF; // Red
const g = (color >> 8) & 0xFF; // Green
const b = color & 0xFF; // Blue
return { r, g, b };
}
// Combine RGB into single value
function combineRGB(r, g, b) {
return (r << 16) | (g << 8) | b;
}
const purple = 0x800080;
console.log(extractRGB(purple)); // {r: 128, g: 0, b: 128}
⚡ Performance Optimizations
Bitwise operations are extremely fast and used in performance-critical code.
// Fast even/odd check
function isEven(n) {
return (n & 1) === 0;
}
// Fast multiplication/division by powers of 2
function multiplyBy8(n) {
return n << 3; // Much faster than n * 8
}
function divideBy4(n) {
return n >> 2; // Much faster than Math.floor(n / 4)
}
// Fast absolute value for 32-bit integers
function fastAbs(n) {
const mask = n >> 31;
return (n + mask) ^ mask;
}
🎯 Bit Flags in React
React internally uses bitwise operations for managing component update priorities.
// Feature flags system
const FEATURES = {
DARK_MODE: 1, // 0001
NOTIFICATIONS: 2, // 0010
ANALYTICS: 4, // 0100
BETA_FEATURES: 8 // 1000
};
class FeatureManager {
constructor() {
this.flags = 0;
}
enable(feature) {
this.flags |= feature;
}
disable(feature) {
this.flags &= ~feature;
}
isEnabled(feature) {
return (this.flags & feature) !== 0;
}
}
const features = new FeatureManager();
features.enable(FEATURES.DARK_MODE | FEATURES.NOTIFICATIONS);
console.log(features.isEnabled(FEATURES.DARK_MODE)); // true
🔢 Hash Functions
Bitwise operations are fundamental in creating hash functions for data structures.
// Simple hash function using bitwise operations
function simpleHash(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32-bit integer
}
return hash;
}
// Bloom filter implementation
class BloomFilter {
constructor(size) {
this.size = size;
this.bits = new Array(Math.ceil(size / 32)).fill(0);
}
add(item) {
const hash1 = this.hash1(item) % this.size;
const hash2 = this.hash2(item) % this.size;
this.setBit(hash1);
this.setBit(hash2);
}
setBit(index) {
const arrayIndex = Math.floor(index / 32);
const bitIndex = index % 32;
this.bits[arrayIndex] |= (1 << bitIndex);
}
}
🎮 Game Development
Bitwise operations are crucial in game development for state management and optimizations.
// Game entity state flags
const ENTITY_FLAGS = {
ALIVE: 1,
MOVING: 2,
ATTACKING: 4,
DEFENDING: 8,
INVISIBLE: 16
};
class GameEntity {
constructor() {
this.flags = ENTITY_FLAGS.ALIVE;
}
addState(state) {
this.flags |= state;
}
removeState(state) {
this.flags &= ~state;
}
hasState(state) {
return (this.flags & state) !== 0;
}
// Toggle state
toggleState(state) {
this.flags ^= state;
}
}
const player = new GameEntity();
player.addState(ENTITY_FLAGS.MOVING | ENTITY_FLAGS.ATTACKING);
console.log(player.hasState(ENTITY_FLAGS.MOVING)); // true
External Resources & Further Learning
📚 Recommended Resources
Comprehensive documentation with examples and browser compatibility
Detailed tutorial with interactive examples and practical applications
Practice problems to master bitwise operations
Coding challenges focused on bitwise operations
Collection of efficient bit manipulation techniques
Visual explanation of how bitwise operations work
Tools for Learning
Books & Advanced Reading
- 📚 "Hacker's Delight" by Henry S. Warren Jr.
- 📚 "Computer Systems: A Programmer's Perspective" by Bryant & O'Hallaron
- 📚 "The Art of Computer Programming" by Donald Knuth
- 📚 "Bitwise: A Life in Code" by David Auerbach
Quick Reference Cheat Sheet
// Common Bitwise Patterns
// Check if number is power of 2
function isPowerOfTwo(n) {
return n > 0 && (n & (n - 1)) === 0;
}
// Count number of set bits (1s)
function countSetBits(n) {
let count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
// Find the only non-duplicate in array
function findSingle(arr) {
return arr.reduce((a, b) => a ^ b, 0);
}
// Check if nth bit is set
function isBitSet(num, n) {
return (num & (1 << n)) !== 0;
}
// Set nth bit
function setBit(num, n) {
return num | (1 << n);
}
// Clear nth bit
function clearBit(num, n) {
return num & ~(1 << n);
}
// Toggle nth bit
function toggleBit(num, n) {
return num ^ (1 << n);
}