While somewhat hard to understand, these operators allow you to perform operations at a binary level, allowing you to manipulate the bits themselves.
Of course, to use bitwise operators, you will need at least a basic understanding of binary numbers. Therefore, we will briefly cover binary numbers within the tutorial to at least get a very entry-level understanding of how all the bitwise mathematics works.
|&||Bitwise AND||x & y||If both bits are |
||||Bitwise OR||x | y||If one of either paired bits is |
|^||Bitwise XOR||x ^ y||If only one of a paired bit is |
|~||Bitwise NOT||~ x||Inverts all bits, |
|<<||Zero Fill Left Shit||x << y||Shift left by pushing zeroes in from the right, left bits will fall off.|
|>>||Sign-propagating right shift||x >> y||Shift right by pushing copies of leftmost bit from left. Right-most bits will fall off.|
By copying the leftmost bit, the number should retain its “sign”.
|>>>||Zero-fill right shift||x >>> y||Shift right by pushing zeroes in from the left. Right-most bits will fall off.|
0) or negative (
A signed number also restricts you to a smaller number. For instance, the limit of a signed 32-bit number is
2147483647. Whereas the limit for an unsigned number is
A 32-bit number with the value of
0 would look like the following. You can see that all 32-bits are set to 0 since no value is currently set.
When counting a binary number, you read from the right, with the right-most bit representing the number
1. Every bit after doubles in value. So bit
8 and so on.
So if we were to have the number 6, we would need to set both bit
3 and bit
1, as shown below. Again remember that you write from right to left.
For example the number 32 could be written like the following in binary using only 8 bits.
From this, you can see why we will be ignoring the other 24 bits of memory when explaining some of the bitwise math for simplicity’s sake.
On top of exploring how these operators work, we will also explain how this bitwise math works.
Bitwise AND Operator (
The bitwise AND operator (
&) works by returning a 1 in each position where both left and right operands contain a
&), and finally the right operand.
The value on the left will be compared against the value on the right using the AND operation.
a & b
To give you a better understanding of how this works let us start with this table. This table shows each value an operand can be and the resulting bit from using the AND operator.
|a||b||a AND (|
Example of AND Binary Math
To showcase this, we will AND the numbers 30 (
00011110) and 6 (
00000110). Remember only bit pairs that are both “
1” will be carried over to the new number.
1. We need to start by expressing both of our numbers as 8-bit binary numbers. Remember, each bit going from right to left is double the previous bit. So, add the bits that add up to your number.
30 = 00011110 6 = 00000110
2. Now that we have our values in a binary format, we can AND each bit pair together.
Remember to write a “
1” when both bits are
1 and a
0 when they are not.
00011110 & 00000110
3. The final result shows that we copied over only bit pairs where both values were
1 to the new result.
Converting this number from binary to decimal should leave you with the number 6.
00000110 = 6
So let us start by declaring two variables. The first variable will be called “
a” and will have the value “
30“. The second variable will have the name “
b” and have the value “
Within a “
console.log()” function call, we will use the bitwise AND operator on both our “
a” and “
b” variables. The resulting operation will be logged to the console.
let a = 30; //00000000000000000000000000011110 let b = 6; //00000000000000000000000000000110 console.log(a & b); //00000000000000000000000000000110
After running the above example, you should end up with the following value in your console.
Bitwise OR Operator (
|) compares each bit pair and will set
1 in that position if either of the bits is
a | b
Let us break out another handy table to make this easy to understand. This table will show each occurrence in which the bitwise OR operator sets bits to
1 instead of
|a||b||a OR (|
Using this table above as a reference, you can see that whenever either of the bits is
1, the resulting bit is
Example of OR Binary Math
We will use the numbers 30 (
00011110) and 5 (
00000101) for this calculation. We will bitwise OR both of these values together. If any of the bits in the pair are
1, we will write down
1. Start by expressing both of our numbers as an 8-bit signed binary number.
Remember that we count from the right to the left when reading binary.
30 = 00011110 5 = 00000101
2. Next, we need to OR our two binary values together. This involves comparing each bit pair and writing down
1 whenever either of the bits is
00011110 | 00000101
3. After comparing both binary numbers, you should end up with the following result. Converting the number back from binary to decimal should leave you with the value of
00011111 = 31
|) in between two operands. JS will handle all the grunt work of handling these numbers as 32-bit binary.
For this example, let us create a variable called “
a” and assign it the value
30. We will also create a variable called “
b” that we will give the value
Finally, we then use the bitwise OR on both our “
a” and “
b” variables, logging the result using the “
let a = 30; //00000000000000000000000000011110 let b = 5; //00000000000000000000000000000101 console.log(a | b); //00000000000000000000000000011111
The above example code should produce the following result. This shows you the result of the bitwise OR operation.
Bitwise XOR Operator (
The bitwise XOR Operator (
1 bit in that position when only one of those bits is
1. If both bits are
1, then the XOR operator will return
0 for that position, hence why it’s called eXclusive OR.
^), and finally the right operand.
a ^ b
Let us write a simple truth table to understand how the XOR operator works. This table will show the only cases in which the XOR operator will set a
|a||b||a XOR (|
Example of XOR Binary Math
1. For this example, we will be calculating the bitwise XOR of the numbers
5. However, before doing this we must first express both numbers as binary.
For simplicity’s sake, we will write both of these numbers as 8-bit binary.
30 = 00011110 5 = 00000101
2. Next, we need to perform an XOR on each of the bit pairs.
Look through each pair of bits and write “
1” whenever there is only one “
1” in the pair. If both are “
0“, or both are “
1” then you need to write “
00011110 ^ 00000101
3. After comparing each bit using the XOR method, you should end up with the following result. Converting the binary number back to the decimal format should leave you with the number 27.
00011011 = 27
For this example, we will declare two variables, one called “
a” and one called “
b“. The “
a” variable will be assigned the value of
30, and the “
b” variable the value of
^) on these two operands and log the result to the console.
let a = 30; //00000000000000000000000000011110 let b = 5; //00000000000000000000000000000101 console.log(a ^ b); //00000000000000000000000000011011
After running the above example, you should end up with the result of the XOR operation in your console.
Bitwise NOT Operator (
The bitwise NOT operator (
If a bit is
0, the bitwise NOT operator will flip it to
1. If the bit is
1 then it will be flipped to
To use this operator, all you need to do is use the tilde symbol (
~), followed by your value or variable name, as shown below.
Example of NOT Binary Math
1. Since the NOT operator only works with a single operand, we will only need one number to show this.
For this example, we will be using the number “
5“, which we will convert to a signed 8-bit binary number.
5 = 00000101
2. With our decimal number converted to binary, we can perform the NOT operation on it. This means for every bit that is
0, we write a
1, and for every bit that is
1, we will write down a
3. Now, you will end up with the following signed number. If you had a negative number, it would have become positive, and if you had a positive number, it would have become negative.
On top of the changed sign, the value of your number will also be different. For example, positive 5 will not be negative 5 when the binary is inverted, as you will soon see.
Converting a negative signed number back to a decimal number means using “two’s complement” in most modern binary number systems.
11111010 - Signed Negative Number
4. We won’t be explaining how exactly two complement works and why, but let us quickly use it to convert our signed negative binary number back to the decimal format.
Start by finding the first “
1” from the right.
Once found, invert all the bits to the left, so
Once you have inverted all the bits, you are left with a binary number that you can now read back as a decimal number. Remember to carry over the negative sign to the final number,
11111010 00000110 = -6
~). You use this character before your variable.
With this example, we will declare a variable called “
a” and assign it the value
5. This variable is what we will use the NOT operator on.
On our next line, we use the NOT operator on our “
a” variable, logging the resulting value
let a = 5; //00000000000000000000000000000101 console.log(~a); //11111111111111111111111111111010
Bitwise Left Shift Operator (
The bitwise left-shift operator (
Any excess bit on the left side is dropped off during the shifting process.
Two less-than signs represent the left shift operator. The left operand is the variable you want to shift. The right operand is how many bits you want to shift to the left by.
a << b
For example, if you have the number
00000001) and bit shift it by
1 position to the left, the value would change to “2” (
If you wanted to replicate this behavior without using bitwise operators, it would be the equivalent of using the following math.
x * (2 ** y)
You would multiply your value by
2 to the power of
y” in this case would be how many places you would want to shift your bits to the left. Computation-wise, shifting the bits is a lot faster.
Quick Explanation of the Left Shift Operator
Bitwise shifting can be somewhat confusing to understand at first but is very straightforward.
1. Let us take the number
1 and convert that into an 8-bit signed binary number.
The value of
1 means we only have the far-right bit set to “
1“, as shown below.
1 = 00000001
2. Now, let us shift this binary number to the left (
<<) by one bit.
We do this by deleting the far-left bit (0 in our example) and adding a new “
0” bit on the right side. From this, you can see how our number
1 in binary had its value changed.
00000001 << 1 00000010 - Value shifted to Left by 1 bit
3. If we were to convert our shifted binary value back to the decimal format, you can see that our value has now changed from “
1” to “
Now, if we were to shift our original
1 value by two places, we would have ended up with the value “
4” instead, as our bit would now be in the third position.
00000010 = 2
At the top of this script, we declare two variables with the names “
a” and “
b“. The “
a” variable is the variable we will be shifting, and we will assign it the value
b” variable is the number of bits we want to shift our number by, which we will set to
Finally, we left-shift the “
a” variable by the “
b” variable, logging the result to the console.
let a = 7; //00000000000000000000000000000111 let b = 2; //00000000000000000000000000000010 console.log(a << b); //00000000000000000000000000011100
Bitwise Sign-Propagating Right Shift Operator (
>>). The first of these is the “sign-propagating right-shift operator”, this operator is designed to preserve the “sign” bit.
>>). The left operand is the variable or value you want to shift, and the right operand is how many bits you want to shift it by.
a >> b
Quick Overview of the Bitwise Sign-Propagating Right-Shift Operator
1. For this example, let us take the number
-7 and convert it to an 8-bit binary number to make this easier to explain.
Suppose this converted number looks weird to you. It’s because we are using two’s complements. This means starting from the first “
1” from the right, we flip each bit to it’s opposite. Converting the number to its signed negative equivalent.
7 = 0000111 -7 = 1111001
-7” value and shifted to the right by two bits, the following would happen.
First, remove the two far-right bits from your binary number. Since we are shifting by two bits, these will need to be dropped.
Next, make a note of the far-left bit. In our case, this is a “
1“, meaning we add two “
1” bits to the start of the number, shifting the overall value to the right.
If your left-most bit were a “
0“, then that would be shifted in from the left instead.
1111001 << 2 1111110 - Shifted to right by 2 bits. Left bit is replicated and shifted in
3. Let us now unravel our number to see how shifting the value by two bits affected its value.
Find the right-most “
1” bit, and flip every bit after that. So a
1 becomes a
0, and a
0 becomes a
4. Finally, reading our binary value and carrying over the “sign” bit, we ended up with the following negative value.
With this, you can see how the right shift changed our value from
0000010 = -2
To show how this works, we will be using the number “
a) and shifting it to the right by 2 (
b) bits. Thanks to preserving the sign of our number, it will remain a negative number after the shift.
We shift our “
a” variable’s binary value to the right by the amount stored in the “
b” variable. The result of the sign-propagating right-shift operation is logged to the console.
let a = -7; //11111111111111111111111111111001 let b = 2; //00000000000000000000000000000010 console.log(a >> b); //11111111111111111111111111111110
Unsigned Bitwise Right Shift Operator (
This operator is represented by three greater-than signs (
>>>). The operand on the left will be shifted by right value. Zeroes will be pushed from the left, with excess bits on the right being dropped.
a >>> b
Since this operation works without regard for a “
signed” number, a negative value will become a rather significant positive value.
As mentioned before, this operator pushes 0’s in from the left, meaning it will not respect the sign of your number
1. Let us showcase this by starting with the number
-7 and converting it to a binary number that we can work with.
We will be sticking to a small 8-bit binary number to make this easy to explain. Since this is a negative number, we will be using two’s complement.
7 = 0000111 -7 = 1111001
2. Now that we have our binary number, let us perform an unsigned right-shift operator to this number.
We will be shifting this number by two bits to the right. Being unsigned means, we will be adding
0‘s from the left side.
Start by dropping off the two far-right bits from the number. These bits will drop off during the unsigned right shift.
Next, add two
0‘s to the front of your binary number, shifting its value to the right.
1111001 >>> 2 0011110 - Unsigned shift to the right. '0' bits added
3. The first thing you will notice is that the sign of our number has now been moved as
0‘s were pushed. This means our number is no longer negative, so you cant use two’s complement to unravel it.
You just need to read the number back as you normally would, counting from right to left. However, you will see that the number is drastically different.
0011110 = 30
We will start our script by declaring a variable called “
a” and assigning it the number
10. Additionally, we will be defining a variable called “
b” and assigning it the number
After we have declared those variables, we utilize the unsigned right-shift operator (
>>>). We use this operator to shift our “
a” variable to the right by the value stored in the “
The result of this bitwise operation is logged to the console using the “
let a = 10; //00000000000000000000000000001010 let b = 3; //00000000000000000000000000000011 console.log(a >>> 3); //00000000000000000000000000000001
The code above will log the following value to the console.
0‘s, it will break the “sign” bit.
At the top of this example script, we will define two variables. The “
a” variable will have the value
-7. With the “
b” variable, we will assign the value
By using the unsigned right-shift operator (
>>>), we will shift our “
a” variable to the right by the amount stored in the “
Like our other examples, we log the result of this bitwise operator to the console.
let a = -7; //11111111111111111111111111111001 let b = 2; //00000000000000000000000000000010 console.log(a >>> b); //00111111111111111111111111111110
Bitwise operators allow you to manipulate numbers at a binary level using various methods. We have explained each of these operators, so you should have a decent idea of what is occurring.
Please comment below if you have any questions about bitwise operators.