But, for the sake of learning we shall understand what and how bit level operators work.
Types of Bitwise Operators
There are many types of bitwise operators that manipulate operands at bit level. Here is a list of bitwise operators which we will discuss with examples later in this post.
|&||Bitwise AND||1 & 1 gives 1 and 1 & 0 gives 0 or vice-versa.|
||||Bitwise OR||1 | 1 gives 1 and 1 & 0 gives 1 also, and vice-versa.|
|^||Bitwise XOR||If any bitwise is 1 then result is 1, else it is 0 for all other situations.|
|<<||Bitwise Left shift||Shift a specified number of bits to the left.|
|>>||Bitwise Right shift||Shift a specified number of bits to the right. It is sign preserving shift.|
|~||Bitwise NOT||This is a unary operator that inverts all the bits of the operand.|
|>>>||Bitwise Zero-filled Right shift||This is the right shift that shift number bits to the right, but fill zero to the left. The result is always non-negative number. (unsigned binary number)|
In the figure above, we have a 8-bit signed binary number and the leftmost bit is called sign bit. A 1-bit is negative number and 0-bit is a positive number. Note that the negative numbers are represented in 2’s complement form.
// 32-bit representation of 4 00000000 00000000 00000000 00000100 //perform an bitwise NOT will inverse all bits 11111111 11111111 11111111 11111011 //The above number is a 2's complement form of a negative number because the sign bit is 1. //Output: -5
Bitwise AND ( & )
The bitwise AND takes two operands and then compares each bit position, since each operand is of 32-bits. If a nth-bit position has 1 in both the operand, then the result will also have 1 in the nth-bit position.
If nth-bit position has a 0 in any one of the operands, the result will have a 0 in the nth-bit position. Consider the following example.
6 & 2 = 0110 0010 ====== 0010 = 2 ======
//variable declaration var x = 6; var y = 2; console.log(x & y); //output : 2
ANDing negative numbers
-5 & 1 = 1011 0001 ========= 0001 = 1 =========
//variable declaration var x = -5; var y = 1; console.log(x & y); //output : 1
The bitwise OR takes two operands and compares each bit positions of both the operands. If nth-bit position has a 1 in any one of the operands, then the nth-bit position of result will also have 1 in it. Only when nth-bit position of both operands are 0, the nth-bit of the result is 0.
5 | 3 = 0101 0011 ======= 0111 = 7 =======
//variable declarations var a = 5; var b = 3; console.log(a | b); //output: 7
ORing with negative numbers
-6 | 2 = 1010 0010 ======= 1010 = -6 =======
//variable declaration var x= -7; var y = 4; console.log(x | y); //output: // -7 = 1001 // 4 = 0100 // ========= // 1101 = -3
Bitwise XOR (^)
Now consider the following example, in this we will XOR each each bit position in both the operands.
5 ^ 3 = 0101 0011 ================ 0110 = 6 ================
//variable declarations var x = 6; var y = 4; console.log(x ^ y); //Output: // 6 = 0110 // 4 = 0100 //=========== // 0010 = 2
XORing negative numbers
-4 ^ 3 = 1100 0011 =============== 1111 = -1 ===============
//variable declarations var x = -7; var y = 2; console.log(x ^ y); //Output: // -7 = 1001 // 2 = 0010 // ========== // 1011 = -5
Bitwise Left Shift (<<)
Bitwise left shift (<<) is also available in other programming languages such as Java, C/C++, etc. This operator takes two operands.
//bitwise left shift syntax <operand 1> << <operand 2>
- Operand 1 holds the value whose bits are left shifted.
- Operand 2 is the number of bits to be shifted.
The Bitwise left shift operator changes the values to its binary equivalent and perform three activities during the shift:
- Shift left the number of bits specified in the operand 2.
- The right most bits of operand 1 is discarded by number of bits specified in operand 2.
- Fill the leftmost bits of operand 1 by number of zeros specified operand 2.
a = 7 // 00000111 b = 3 a << b //left shift 3 bits and discard 3 bits from left. // 00111 // add three zero from the right. //00111000 = 56
variable declarations var a = 7; var b = 3; //left shift var c = a << b; console.log(c); //Output: 56
Bitwise Right Shift (>>)
The bitwise right shift is similar to bitwise left shift operator. It also accepts two operands – one whose bits are shifted right, and the second operand specifies the number of bits to be shifted.
Since, numbers are in 32-bit signed binary format, the leftmost bit is either positive or negative. If positive, then it is 0 and if negative, then it is 1. Three things happen which right shift operation is performed:
- The bits of operand 1 is shifted right to the number specified by operand 2.
- The bits of operand 1 is discarded from right by the number specified by operand 2.
- If the number is positive, fill left-side of operand 1 with number of zeros specified in the operand 2.
- If the number is negative, fill left-side of the operand 1 with number of 1s specified in the operand 2.
Due to filling the left-side of operand 1 with either 0 or 1, the right shift operator is also known as “Sign preserving shift”.
a = -5 // 11111011 b = 2 a >> b //right shift 2 bits and discard 2 bits from right. // 111110 // add three 1s from the left //11111110 = -2
variable declarations var a = -5; var b = 2; //right shift c = a >> b; console.log(c); //Output: -2
Note how bitwise right shift (>>) preserves the negative sign in the output .
Bitwise Zero-Fill Right Shift (>>>)
The idea behind the bitwise zero-fill right shift (>>>) is to shift bits to the right, but the number must not preserve the sign.The output is always a non-negative number.
a = -9; //11110111 b = 2 //zero-fill right shift by 2 bits a >>> b //output : 001111001 = 1073741821
//variable declarations var a = -9;//11110111 var b = 2; //zero fill right shift by 2 bits var c = a >>> b; console.log(c); //output : 001111001 = 1073741821
Note that for negative number the output is expected number = 1073741821 which is correct. This is because we don’t preserve the sign bit and 1073741821 is result of unsigned binary representation of the number.