Bitwise operations in JavaScript operate directly on the binary representations of numbers. These operations are performed at the bit level, which makes them useful for tasks like low-level programming, working with binary data, manipulating flags, or performing calculations in certain algorithms.
In JavaScript, numbers are stored as 64-bit floating-point numbers, but bitwise operations convert these numbers to 32-bit signed integers before performing any operations. After the operation, the result is converted back to a JavaScript number.
In this tutorial, we will explore the different types of bitwise operators in JavaScript, their usage, and examples to understand how they work.
1. Bitwise Operators in JavaScript
JavaScript supports the following bitwise operators:
AND (&): Sets each bit to 1 if both bits are 1.
OR (|): Sets each bit to 1 if at least one of the bits is 1.
XOR (^): Sets each bit to 1 if exactly one of the bits is 1.
NOT (~): Inverts all the bits.
Left Shift (<<): Shifts the bits to the left by a specified number of positions. Right Shift (>>): Shifts the bits to the right, preserving the sign (sign-propagating).
Unsigned Right Shift (>>>): Shifts the bits to the right, filling the leftmost bits with zeros (zero-filling).
2. Bitwise AND (&)
The bitwise AND operator compares each bit of two numbers. If both bits are 1, the resulting bit is set to 1; otherwise, it is set to 0.
Example 1: Bitwise AND
const a = 5; // Binary: 0101 const b = 3; // Binary: 0011 const result = a & b; // Binary: 0001 (decimal: 1) console.log(result); // Output: 1
Explanation:
5 in binary is 0101.
3 in binary is 0011.
The result of 0101 & 0011 is 0001, which is 1 in decimal.
3. Bitwise OR (|)
The bitwise OR operator compares each bit of two numbers. If at least one of the bits is 1, the resulting bit is set to 1.
Example 2: Bitwise OR
const a = 5; // Binary: 0101 const b = 3; // Binary: 0011 const result = a | b; // Binary: 0111 (decimal: 7) console.log(result); // Output: 7
Explanation:
5 in binary is 0101.
3 in binary is 0011.
The result of 0101 | 0011 is 0111, which is 7 in decimal.
4. Bitwise XOR (^)
The bitwise XOR operator compares each bit of two numbers. If the bits are different, the resulting bit is set to 1; otherwise, it is set to 0.
Example 3: Bitwise XOR
const a = 5; // Binary: 0101 const b = 3; // Binary: 0011 const result = a ^ b; // Binary: 0110 (decimal: 6) console.log(result); // Output: 6
Explanation:
5 in binary is 0101.
3 in binary is 0011.
The result of 0101 ^ 0011 is 0110, which is 6 in decimal.
5. Bitwise NOT (~)
The bitwise NOT operator inverts all the bits of a number, including the sign bit. This operation returns the two's complement of the number.
Example 4: Bitwise NOT
const a = 5; // Binary: 0101 const result = ~a; // Binary: 1010 (decimal: -6) console.log(result); // Output: -6
Explanation:
5 in binary is 00000000000000000000000000000101.
Applying ~ inverts all bits, resulting in 11111111111111111111111111111010, which is -6 in decimal.
6. Bitwise Left Shift (<<)
The left shift operator (<<) shifts the bits of a number to the left by a specified number of positions, filling the rightmost bits with zeros.
Example 5: Left Shift
const a = 5; // Binary: 0101 const result = a << 2; // Binary: 00010100 (decimal: 20) console.log(result); // Output: 20
Explanation:
5 in binary is 0101.
Shifting 0101 two positions to the left results in 00010100, which is 20 in decimal.
7. Bitwise Right Shift (>>)
The right shift operator (>>) shifts the bits of a number to the right by a specified number of positions, preserving the sign (sign-propagating).
Example 6: Right Shift
const a = -10; // Binary (32-bit): 11111111111111111111111111110110 const result = a >> 2; // Binary: 11111111111111111111111111111101 (decimal: -3) console.log(result); // Output: -3
Explanation:
-10 in binary (two's complement) is 11111111111111111111111111110110.
Shifting right by 2 positions results in 11111111111111111111111111111101, which is -3 in decimal.
8. Unsigned Right Shift (>>>)
The unsigned right shift operator (>>>) shifts the bits of a number to the right by a specified number of positions, filling the leftmost bits with zeros. This operation treats the number as an unsigned 32-bit integer, which means it does not preserve the sign.
Example 7: Unsigned Right Shift
const a = -10; // Binary (32-bit): 11111111111111111111111111110110 const result = a >>> 2; // Binary: 00111111111111111111111111111101 (decimal: 1073741821) console.log(result); // Output: 1073741821
Explanation:
-10 in binary (two's complement) is 11111111111111111111111111110110.
Shifting right by 2 positions using >>> results in 00111111111111111111111111111101, which is 1073741821 in decimal.
9. Practical Use Cases for Bitwise Operations
Example 8: Setting, Clearing, and Toggling Bits
You can use bitwise operations to manipulate individual bits in a number.
const FLAG_A = 1 << 0; // 0001 const FLAG_B = 1 << 1; // 0010 const FLAG_C = 1 << 2; // 0100 // Setting FLAG_A and FLAG_C let flags = 0; flags |= FLAG_A | FLAG_C; // 0101 console.log(flags); // Output: 5 // Clearing FLAG_C flags &= ~FLAG_C; // 0001 console.log(flags); // Output: 1 // Toggling FLAG_B flags ^= FLAG_B; // 0011 console.log(flags); // Output: 3
Explanation:
Setting bits: Use | (OR) to set specific bits.
Clearing bits: Use & (AND) with the negation of the flag (~FLAG).
Toggling bits: Use ^ (XOR) to flip the bit's state.
Example 9: Checking if a Bit is Set
const FLAG_A = 1 << 0; // 0001 const flags = 5; // 0101 const isFlagASet = (flags & FLAG_A) !== 0; console.log(isFlagASet); // Output: true
Explanation: Use the & (AND) operator to check if a specific bit is set.
Conclusion
Bitwise operations are powerful tools for manipulating binary data at the bit level. They are particularly useful in scenarios where you need to work with flags, binary data processing, low-level data structures, and performance-critical applications.
Key Takeaways:
Bitwise AND (&): Sets bits to 1 if both corresponding bits are 1.
Bitwise OR (|): Sets bits to 1 if at least one of the corresponding bits is 1.
Bitwise XOR (^): Sets bits to 1 if exactly one of the corresponding bits is 1.
Bitwise NOT (~): Inverts all the bits.
Left Shift (<<): Shifts bits to the left, filling with zeros. Right Shift (>>): Shifts bits to the right, preserving the sign.
Unsigned Right Shift (>>>): Shifts bits to the right, filling with zeros.
Experiment with these bitwise operators to get a better grasp of how they can be used to manipulate data in various scenarios!