Bitwise operators in JavaScript
The table below summarizes the bitwise operators in JavaScript:
Operator | Usage | Result |
---|---|---|
Bitwise AND | a & b | Returns 1 for each bit position where both operands are 1 |
Bitwise OR | a | b | Returns 1 for each bit position where either operand is 1 |
Bitwise XOR | a ^ b | Returns 1 for each bit position where either but not both are 1 |
Left shift | a << b | Shifts in binary fashion all bits one position to the left; discarding the left bit and filling the right bit with 0. |
Right shift | a >> b | Shifts in binary fashion all bits one position to the right, discarding the right bit. This operations maintains the original sign (+ or -). |
0-fill right shift | a >>> b | Shifts in binary fashion all bits one position to the right, discarding the right bit and filling the left bit with 0. |
JavaScript does not support an integer type. All numbers in JavaScript are stored in 64-bit floating point format i.e. double precision floating point. The bitwise operators that manipulate numbers at the bit level do not perform operations directly on this 64-bit floating-point representation. Instead, they coerce the numeric values to signed 32-bit integers, do the necessary operation, and again convert the result back to floating point format. This conversion has a performance impact.
You get the correct results for only up to 32 bits. During the conversion to 32-bit, the fractional part and any bits beyond the 32nd are dropped. If you have more bits than that, the value gets rounded to the nearest representable floating-point number.
- var a = 0xFFFFFFFFF; // => 36 bits all set to 1
- var b = 0xFFFFFFFFF; // => 36 bits all set to 1
- var c = a & b; // bitwise AND
- alert(c); // => -1
You may expect that c's value has all 36 bits set to 1 following the bitwise & operation, but because of the conversion to 32-bits that is not the case. JavaScript converts to 32-bit, executes the bitwise AND operation, and the resulting 32-bits are all set to 1 which is equal to -1.
Let's look at an example with floating point numbers:
- var a = 2.6; // represented as bits 0010, fractional part discarded
- var b = 6.2 // represented as bits 0110, fractional part discarded
- var c = a & b; // => bits 0010, which is equal to 2
- alert(c); // => 2
Strangely, if you use NaN, Infinity, or -Infinity as operands in bitwise operations, they are converted to 0.
In all C-like languages, bitwise operators are extremely fast. Until recently, they were slow in JavaScript but the latest versions of web browsers can JIT-compile JavaScript code. These operations have accelerated enough to be useful.
Bitwise manipulations are typically close to the hardware and therefore they don't come up very often in JavaScript programming.
A common mistake it to use bitwise & and | operators instead of logical && and || operators. This can lead to hard-to-detect bugs. Here is what may happen. Say we have a variable x with a value of 5 and you have mistakenly typed & instead of &&.
- var x = 5;
- if (x > 5 & x < 8) {
- alert(true);
- } else {
- alert(false);
- }
This is false, which is the same if you had typed the && operator: if (x<=5 && x>7). Although we are getting the expected result, we have improperly used a logical & operator which is intended for bit-level operations only. Again, be aware of this mistake as it can lead to difficult to find bugs.