ECMAScript Bitwise Operators
- Previous Page Unary Operators
- Next Page Logical Operators
Bitwise operators operate at the lower level of numbers (i.e., the 32 bits that represent the number).
Review integers
ECMAScript integers have two types, namely signed integers (which allow both positive and negative numbers) and unsigned integers (which only allow positive numbers). In ECMAScript, all integer literals are default signed integers, which means what?
Signed integers use 31 bits to represent the value of the integer, and the 32nd bit represents the sign of the integer, 0 for positive numbers and 1 for negative numbers. The value range is from -2147483648 to 2147483647.
There are two different ways to store signed integers in binary form, one for storing positive numbers and one for storing negative numbers. Positive numbers are stored in true binary form, with each bit of the first 31 bits representing a power of 2, starting from the first bit (bit 0), representing 20, the second bit (bit 1) represents 21. The unused bits are filled with 0, which are ignored. For example, the following figure shows the representation of the number 18.

The binary version of 18 only uses the first 5 bits, which are the valid bits of this number. By converting the number to a binary string, you can see the valid bits:
var iNum = 18; alert(iNum.toString(2)); // Outputs "10010"
This code only outputs "10010", not the 32-bit representation of 18. The other digits are not important because only the first 5 bits are needed to determine this decimal number. As shown in the following figure:

Negative numbers are also stored as binary codes, but in the form of two's complement. There are three steps to calculate the two's complement of a number:
- Determine the binary representation of the non-negative version of the number (for example, to calculate the two's complement of -18, you first need to determine the binary representation of 18)
- Obtain the two's complement, which involves replacing 0 with 1 and 1 with 0
- Add 1 to the two's complement
To determine the binary representation of -18, you must first get the binary representation of 18, as shown below:
0000 0000 0000 0000 0000 0000 0001 0010
Next, calculate the two's complement, as shown below:
1111 1111 1111 1111 1111 1111 1110 1101
Finally, add 1 to the two's complement, as shown below:
1111 1111 1111 1111 1111 1111 1110 1101 1 --------------------------------------- 1111 1111 1111 1111 1111 1111 1110 1110
Therefore, the binary representation of -18 is 1111 1111 1111 1111 1111 1111 1110 1110. Remember that when dealing with signed integers, developers cannot access the 31st bit.
Interestingly, when a negative integer is converted to a binary string, ECMAScript does not display it in two's complement form but outputs it with a negative sign in front of the standard binary code of the absolute value. For example:
var iNum = -18; alert(iNum.toString(2)); // Outputs "-10010"
This code outputs "-10010", not two's complement, to avoid accessing bit 31. For simplicity, ECMAScript handles integers in a straightforward way so that developers do not have to worry about their usage.
On the other hand, unsigned integers treat the last bit as another digit. In this mode, the 32nd bit does not represent the sign of the number but the value 2.31Due to this additional bit, the value range of unsigned integers is from 0 to 4294967295. For integers less than 2147483647, unsigned integers appear the same as signed integers, while integers greater than 2147483647 require the use of bit 31 (which is always 0 in signed integers).
When an unsigned integer is converted to a string, only the significant bits are returned.
Note:All integer literals are stored as signed integers by default. Only ECMAScript's bitwise operators can create unsigned integers.
Bitwise NOT
The bitwise NOT operator, represented by the tilde (~), is one of the few operators in ECMAScript that is related to binary arithmetic.
The NOT bitwise operation is a three-step process:
- Convert the operand to a 32-bit number
- Convert a binary number to its two's complement
- Convert a binary number to a floating-point number
For example:
var iNum1 = 25; //25 equals 00000000000000000000000000011001 var iNum2 = ~iNum1; //Converted to 11111111111111111111111111100110 alert(iNum2); //Output "-26"
The NOT bitwise operation is essentially the negation of the number and then subtracting 1, so 25 becomes -26. The same result can also be obtained by the following method:
var iNum1 = 25; var iNum2 = -iNum1 -1; alert(iNum2); //Output -26
Bitwise AND
The AND bitwise operation is represented by the ampersand (&) and directly operates on the binary form of the number. It aligns the digits of each number and then performs the AND operation on the two digits at the same position using the following rules:
Bits of the first number | Bits of the second number | Result |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
For example, to perform the AND operation on the number 25 and 3, the code is as follows:
var iResult = 25 & 3; alert(iResult); //Output "1"
The result of the AND operation between 25 and 3 is 1. Why? The analysis is as follows:
25 = 0000 0000 0000 0000 0000 0000 0001 1001 3 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- AND = 0000 0000 0000 0000 0000 0000 0000 0001
It can be seen that in 25 and 3, only one digit (bit 0) stores 1, so the other digits generate 0, resulting in 1.
Bitwise OR
The OR bitwise operation is represented by the symbol (|) and directly operates on the binary form of the number. When calculating each digit, the OR operator follows the following rules:
Bits of the first number | Bits of the second number | Result |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
Using the same example as the AND operator, the OR operation between 25 and 3 is as follows:
var iResult = 25 | 3; alert(iResult); //Output "27"
The result of the OR operation between 25 and 3 is 27:
25 = 0000 0000 0000 0000 0000 0000 0001 1001 3 = 0000 0000 0000 0000 0000 0000 0000 0011 -------------------------------------------- OR = 0000 0000 0000 0000 0000 0000 0001 1011
It can be seen that in the two numbers, there are 4 digits that store 1, and these digits are passed to the result. The binary code 11011 is equal to 27.
Bitwise XOR operation
The bitwise XOR operation is represented by the symbol (^), of course, it also operates directly on the binary form. XOR is different from OR, it only returns 1 when only one bit stores the number 1. The truth table is as follows:
Bits of the first number | Bits of the second number | Result |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
The XOR operation between 25 and 3 is as follows:
var iResult = 25 ^ 3; alert(iResult); // Output '26'
The result of the XOR operation between 25 and 3 is 26:
25 = 0000 0000 0000 0000 0000 0000 0001 1001 3 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- XOR = 0000 0000 0000 0000 0000 0000 0001 1010
It can be seen that in the two numbers, there are 4 bits that store the number 1, and these bits are passed on to the result. The binary code 11010 equals 26.
Left shift operation
The left shift operation is represented by two less-than signs (<<). It moves all the bits of a number to the left by the specified amount. For example, shifting the number 2 (which is equal to binary 10) left by 5 bits results in 64 (which is equal to binary 1000000):
var iOld = 2; // equals binary 10 var iNew = iOld << 5; // equals binary 1000000 decimal 64
Note:When shifting the bits to the left, there are 5 empty positions on the right side of the number. The left shift operation fills these empty positions with 0s to make the result a complete 32-bit number.

Note:The left shift operation retains the sign bit of the number. For example, if -2 is left-shifted by 5 bits, the result is -64, not 64. 'Is the sign still stored in the 32nd bit?' Yes, but this is done in the ECMAScript backend, and developers cannot directly access the 32nd bit. Even when outputting the binary string form of a negative number, it is displayed in the form of a negative sign (for example, -2 will display -10).
Signed right shift
The signed right shift operator is represented by two greater-than signs (>>). It shifts all the bits of a 32-bit number to the right as a whole, while retaining the sign of the number (positive or negative). The signed right shift operator is exactly the opposite of the left shift. For example, shifting 64 right by 5 bits results in 2:
var iOld = 64; // equals binary 1000000 var iNew = iOld >> 5; // equals binary 10 decimal 2
Similarly, after shifting the bits, there will be empty positions. This time, the empty positions are located on the left side of the number, but after the sign bit. ECMAScript fills these empty positions with the value of the sign bit to create a complete number, as shown in the following figure:

Unsigned Right Shift Operation
The unsigned right shift operator is represented by three greater than signs (>>>), which shifts all bits of an unsigned 32-bit number as a whole. For positive numbers, the result of the unsigned right shift operation is the same as that of the signed right shift operation.
Using the example of signed right shift, if 64 is right-shifted by 5 bits, it will become 2:
var iOld = 64; // equals binary 1000000 var iNew = iOld >>> 5; // equals binary 10 decimal 2
For negative numbers, the situation is different.
The unsigned right shift operation fills all empty positions with 0. For positive numbers, this is the same as the operation of signed right shift, while negative numbers are treated as positive numbers.
Since the result of an unsigned right shift operation is a 32-bit positive number, the unsigned right shift operation of a negative number always results in a very large number. For example, if -64 is right-shifted by 5 bits, it will get 134217726. How do you get this result?
To achieve this, you need to convert this number to its unsigned equivalent form (even though the number itself is signed), which can be obtained by the following code:
var iUnsigned64 = -64 >>> 0;
Then, use the toString() method of the Number type to get its actual bit representation, using base 2:
alert(iUnsigned64.toString(2));
This will generate 11111111111111111111111111000000, which is the two's complement binary representation of the signed integer -64, but it is equal to the unsigned integer 4294967232.
Therefore, be careful when using the unsigned right shift operator.
- Previous Page Unary Operators
- Next Page Logical Operators