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":
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:
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:
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:
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:
Comments
No comments have been made yet.
Please login to leave a comment. Login now