Bitwise Operators
Bitwise operators work with the binary representation of numbers.
Most JavaScript code uses arithmetic, comparison, and logical operators much more often. Bitwise operators are more advanced and appear in specific situations such as permissions, flags, low-level data handling, graphics, algorithms, and technical interviews.
You do not need bitwise operators for most everyday web development, but understanding them helps you understand how numbers can be manipulated at the bit level.
What Does Bitwise Mean?
Computers store numbers using bits.
A bit is either:
0or:
1For example, the number 5 can be represented in binary as:
0101The number 1 is:
0001Bitwise operators compare or shift these individual bits.
The Important JavaScript Rule
JavaScript numbers are normally stored as 64-bit floating-point values.
But bitwise operators are different.
Before a bitwise operation runs, JavaScript converts the operands to 32-bit signed integers. After the operation, the result is converted back to a normal JavaScript number.
This has important consequences:
- Decimal parts are removed.
- Very large numbers can lose information.
- Bitwise operators are best used with whole numbers.
Example:
console.log(3.9 | 0); // 3The decimal part is removed because bitwise operations work on 32-bit integers.
Core Bitwise Operators
| Operator | Name | Meaning |
|---|---|---|
& |
AND | Bit is 1 only if both bits are 1 |
| ` | ` | OR |
^ |
XOR | Bit is 1 if the bits are different |
~ |
NOT | Inverts all bits |
<< |
Left shift | Moves bits to the left |
>> |
Signed right shift | Moves bits to the right and keeps the sign |
>>> |
Unsigned right shift | Moves bits to the right and fills with 0s |
Bitwise AND
The & operator compares each bit.
It returns 1 only when both bits are 1.
0101 // 5
0001 // 1
----
0001 // 1JavaScript:
console.log(5 & 1); // 1Another example:
0110 // 6
0011 // 3
----
0010 // 2console.log(6 & 3); // 2Bitwise OR
The | operator returns 1 when at least one bit is 1.
0101 // 5
0001 // 1
----
0101 // 5console.log(5 | 1); // 5Another example:
0100 // 4
0010 // 2
----
0110 // 6console.log(4 | 2); // 6Bitwise XOR
The ^ operator returns 1 when the bits are different.
0101 // 5
0001 // 1
----
0100 // 4console.log(5 ^ 1); // 4XOR is useful in some algorithms because it highlights differences between bit patterns.
Bitwise NOT
The ~ operator inverts all bits.
console.log(~5); // -6This result surprises many beginners.
In JavaScript:
~x === -(x + 1)So:
console.log(~5); // -6
console.log(~0); // -1
console.log(~-1); // 0The reason involves 32-bit signed integer representation. You do not need to memorize all the internals yet, but remember that ~ flips every bit.
Left Shift
The << operator shifts bits to the left and fills the right side with 0s.
0101 // 5
1010 // 10console.log(5 << 1); // 10Shifting left by 1 is similar to multiplying by 2.
console.log(5 << 1); // 10
console.log(5 << 2); // 20Use normal multiplication for readability unless you specifically need bitwise behavior.
Signed Right Shift
The >> operator shifts bits to the right while preserving the sign.
console.log(5 >> 1); // 2
console.log(8 >> 1); // 4Shifting right by 1 is similar to dividing by 2 and truncating.
console.log(9 >> 1); // 4For negative numbers, >> keeps the negative sign.
console.log(-8 >> 1); // -4Unsigned Right Shift
The >>> operator shifts bits to the right and fills the left side with 0s.
This can turn negative numbers into large positive 32-bit values.
console.log(-5 >>> 0); // 4294967291This operator is useful in low-level numeric work, but it is uncommon in beginner JavaScript.
Practical Use Case: Odd or Even
The last binary bit of an odd number is 1.
The last binary bit of an even number is 0.
So you can use num & 1 to check odd/even.
const number = 7;
if (number & 1) {
console.log("Odd");
} else {
console.log("Even");
}This works, but the modulo version is more readable for most developers:
if (number % 2 !== 0) {
console.log("Odd");
}Prefer readability unless there is a specific reason to use bitwise operators.
Practical Use Case: Flags and Permissions
Bitwise operators are useful when multiple on/off settings can be stored in one number.
Each permission gets its own bit:
const READ = 1; // 0001
const WRITE = 2; // 0010
const EXECUTE = 4; // 0100Combine permissions with OR:
let permissions = READ | WRITE;
console.log(permissions); // 3Check a permission with AND:
if (permissions & WRITE) {
console.log("User can write");
}Add a permission:
permissions = permissions | EXECUTE;Remove a permission:
permissions = permissions & ~WRITE;This pattern is called bitmasking.
It is common in permissions systems, graphics, game development, operating systems, and low-level APIs.
The Double Tilde
You may see ~~value in JavaScript code.
It applies bitwise NOT twice.
console.log(~~3.14); // 3
console.log(~~-3.14); // -3
console.log(~~"42"); // 42This truncates toward zero.
It is closer to Math.trunc() than Math.floor().
console.log(Math.trunc(-3.14)); // -3
console.log(Math.floor(-3.14)); // -4While ~~ is short, it is not very readable.
Prefer:
Math.trunc(value);or:
Math.floor(value);depending on the behavior you need.
Bitwise OR with Zero
Another shortcut is value | 0.
console.log(3.9 | 0); // 3
console.log("42" | 0); // 42Like ~~, it converts to a 32-bit integer and truncates.
This can be surprising and can break with large numbers.
Prefer explicit methods in most application code.
Common Mistakes
Confusing & with &&
& is bitwise AND.
&& is logical AND.
console.log(5 & 1); // 1
console.log(true && false); // falseThey are not the same operator.
Confusing | with ||
| is bitwise OR.
|| is logical OR.
console.log(4 | 2); // 6
console.log(false || true); // trueThey behave very differently.
Using Bitwise Tricks for Readability-Critical Code
This is clever:
const integer = ~~value;This is clearer:
const integer = Math.trunc(value);Readable code is usually better than clever code.
Using Bitwise Operators with Large Numbers
Bitwise operators convert values to 32-bit integers.
Large numbers may lose data.
console.log(2147483648 | 0); // -2147483648This happens because the value crosses the signed 32-bit integer boundary.
Use bitwise operators only when you understand the 32-bit behavior.
Summary
Bitwise operators work on the 32-bit binary representation of numbers.
Remember:
- JavaScript converts operands to 32-bit signed integers for bitwise operations.
- Decimals are truncated during bitwise operations.
&,|, and^compare bits.~flips bits.<<,>>, and>>>shift bits.- Bitwise operators are useful for flags, permissions, and low-level algorithms.
num & 1can check odd/even, but% 2is usually clearer.~~valueandvalue | 0are truncation shortcuts, butMath.trunc()is more readable.- Do not confuse bitwise operators with logical operators.
Next, you will learn about comparison operators, which are used to compare values and build conditions.