The bitwise operators work with numbers on the core level of programming.

Consider that all numbers are stored in a standard (IEEE-754) 64-bit format. During bitwise operations the values are converted first into 32-bit integers, and after the operation takes place, the result is converted back to a 64-bit format.

These 32-bit integers are actually stored as bits, with the last bit (bit 32) representing the sign; "0" if the number is positive and "1" if negative.

Furthermore, positive numbers are stored in so called TRUE BINARY format, where each bit represents a decimal power of 2, starting with the first bit being 20, the second 21, and so on.

The following example shows the bitwise storage of number "11":

JavaScript bitwise operation diagram

 

 

 

 

As seen above the number "11" is equal to "1011" in binary system. In reality the number is stored with all 32 bits (00000000000000000000000000001011).

The negative numbers are stored as so called TWO's COMPLEMENT format. The calculation goes through three steps; first the number is calculated as it was positive, i.e. number "11", then the one's complement is calculated by replacing the bits with the opposite value (thus all "0" become "1" and vice versa), and finally "+1" binary is added to the result. The entire process is shown in this example:

number "-11":

 

00000000000000000000000000001011 // step one

11111111111111111111111111110100 // step two

11111111111111111111111111110100 // step three

                               1

--------------------------------

11111111111111111111111111110101

The above notes are only the brief introduction into the binary system and signed 32-bit integers, but the matter is naturally somewhat more complex than this. However, the JS hides all of this and just outputs the results as shown below:

var num = -11;

alert(num.toString(2)); // "-1011

The result is actually shown in a more logical instead of the real form.

Although bitwise operations may be performed with regular arithmetic operations, the bitwise operators (see below) work much faster because they are computed on the most basic or lowest level.

Bitwise NOT

The bitwise NOT is represented by a tilde symbol ("~") and it returns the one's complement of the given number. The example is shown below:

var num1 = 25;

var num2 = ~num1; // equals "-26"

The result is "-26" if visualized in decimal format because the "num1" first negates and ten subtracts by one ("-25 ? 1").

Bitwise AND

The bitwise AND is represented by an ampersand symbol ("&") and it works with two values. The result will be "1" only if both values are "1" as shown in the table below:

Bitwise AND
value 1 value 2 result
1 1 1
1 0 0
0 1 0
0 0 0

The following example shows the how calculation works with real numbers:

var val1 = 10;

var val2 = 2;

var res = val1 & val2; // equals "2", here is why:

1011 // 10

0010 // 2

0010 // equals "2"

Bitwise OR

The bitwise OR is represented by a single pipe symbol ("|") and it works with two values. The result will be "1" if at least one of values is "1" as shown in the table below:

Bitwise OR
value 1 value 2 result
1 1 1
1 0 1
0 1 1
0 0 0

The following example shows the how calculation works with real numbers:

var val1 = 10;

var val2 = 2;

var res = val1 | val2; // equals "11", here is why:

1011 // 10

0010 // 2

1011 // equals "11"

Bitwise XOR (exclusive OR)

The bitwise XOR is represented by a caret symbol ("^") and it works with two values. The result will be "1" if only one of values is "1" as shown in the table below:

Bitwise XOR
value 1 value 2 result
1 1 0
1 0 1
0 1 1
0 0 0

 

 

 

 

 

The following example shows the how calculation works with real numbers:

var val1 = 10;

var val2 = 2;

var res = val1 ^ val2; // equals "9", here is why:

1011 // 10

0010 // 2

1001 // equals "9"

Left Shift

The left shift is represented by two less-then symbols ("<<") and it shifts all the bits in a number to the left by the number of positions given. The following example shows the how calculation works with real numbers:

var val1 = 2 // binary 10

var val2 = val1 << 3 // binary 10000 or 16 in decimal format

The 3 new positions on the right are filled with zeros while the 3 last old positions on the left of 32-bit integer are dropped, like this:

val1 = 00000000000000000000000000000010

val2 = 00000000000000000000000000010000

Signed Right Shift

The signed right shift is represented by two greater-than symbols (">>") and it shifts all the bits in a number to the right by the number of positions given, while preserving the sign. The following example shows the how calculation works with real numbers:

var val1 = 16 // binary 10000

var val2 = val1 >> 3 // binary 10 or 2 in decimal format

The 3 new positions on the left are filled with zeros with the very last position remaining intact due representing the sign, while the 3 last old positions on the right of 32-bit integer are dropped, like this:

val1 = 00000000000000000000000000010000

val2 = 00000000000000000000000000000010

Unsigned Right Shift

The unsigned right shift is represented by three greater-than symbols (">>>) and it shifts all the bits in a number to the right by the number of positions given. If the number is positive the results are the same as with signed right shift, while the negative have a completely different effect. Because the negative numbers are two's complement of its absolute value, the number becomes very large, as seen in the following example:

var val1 = -16 // binary 11111111111111111111111111110000

var val2 = val1 >>> 3 // binary 00011111111111111111111111111110 or 536870910 in decimal format

As seen above when working with negative numbers the signed right shift must be used in order to produce proper result.

Example

The example with bitwise operators in JavaScript:

 

›› go to examples ››