An operator

Bitwise operators are used for low-level operations on numbers, that is, operating on bits (bits) that represent data in memory. All values in ECMAScript are stored in IEEE 754 64-bit format, but bitwise operations do not apply directly to 64-bit representations. Instead, values are converted to 32-bit integers, then bitwise operations are performed, and then the result is converted to 64-bit. To the developer, it is as if there were only 32-bit integers, because the 64-bit integer storage format is invisible. So you only need to consider 32-bit integers.

Signed integers use the first 31 bits of 32 bits to represent integer values. The 32nd bit represents a numeric symbol, such as 0 for positive and 1 for negative. This bit is called the sign bit.

0 0000000000000000000000000000000
The sign bit

Comes at a time

Positive values are stored in binary format. There are 31 digits, each of which is a power of two. The first digit (the 0th digit) represents 2 to the 0, the second digit represents 2 to the 1, and so on. The empty space is filled with 0.

For example, the binary format of numerical 18 to 00000000000000000000000000010010, down to 10010. The latter are the five significant bits used:

1 0 0 1 0
1 * * * 2 and 4 0 * 2 * * 3 0 * * 2 * 2 1 * 2 * * 1 0 * 2 * * 0
16 0 0 2 0
And for the 18

negative

Negative values are stored in the binary encoding of the two complements (complement). The binary complement is calculated by three steps:

  1. You get the binary of absolute value
  2. Make all the ones 0 and all the zeros 1 to get a complement.
  3. Add 1 to the result

Determine the binary representation of -18 based on the above steps:

The absolute value of 18

0000 0000 0000 0000 0000 0001 0010

Computes a complement, that is, inverts the binary value of each bit:

1111 1111 1111 1111 1111 1111 1110 1101

Finally, add 1 to a complement:

1111 1111 1111 1111 1111 1111 1110 1110

When we print a negative value as a binary string, we get an absolute value preceded by a minus sign:

let num = -18;
console.log(num.toString(2)); / / "- 10010"
Copy the code

By default, all integers in ECMAScript are represented as signed numbers. However, unsigned integers do exist. For unsigned integers, the 32nd (31st) bit does not represent a sign because there are only positive values. Unsigned integers have a larger range than signed integers because sign bits are used to represent values.

When bitwise operators are applied to ECMAScript values, conversion takes place behind the scenes: 64-bit values are converted to 32-bit values, bitwise operations are performed, and the result is converted from 32-bit to 64-bit for storage. This conversion causes a peculiar side effect, in that the special values NaN and Infinity are treated as zero in in-place operations.

If bitwise operators are applied to non-numeric values, Number() is converted first. The end result is a number.

According to a non

Represented by ~, returns the complement (inverse code) of the numeric value. Bitwise non can return the negative value of the value and subtract 1:

let num1 = 25; / / binary 00000000000000000000000000011001
let num2 = ~num1; / / binary 11111111111111111111111111100110
console.log(num2); / / - 26
Copy the code

And this operation is much faster than the following:

let num1 = 25;
let num2 = -num1 - 1;
console.log(num2); / / "- 26"
Copy the code

Bitwise and

I’ll call it ampersand. Bitwise aligns each bit of the two numbers and then performs and operates on each bit based on the rules in the truth table.

The bits of the first number The bits of the second value Bear fruit
1 1 1
1 0 0
0 1 0
0 0 0

We bitwise sum the values 25 and 3:

let result = 25 & 3;
console.log(result); / / 1
Copy the code

What happens in this process?

25 = 0000 0000 0000 0000 0000 0000 0001

3 = 0000 0000 0000 0000 0000 0000 0000


AND = 0000 0000 0000 0000 0000 0000 0000 0001

Bitwise or

Use | said. follow

The bits of the first number The bits of the second value Bear fruit
1 1 1
1 0 1
0 1 1
0 0 0
Everything else is the same as bitwise and, no more repeated examples.

The bitwise exclusive or

Let’s call it ^. follow

The bits of the first number The bits of the second value Bear fruit
1 1 0
1 0 1
0 1 1
0 0 0
Same as above

Shift to the left

The left-shift operator is represented by <<. Moves all bits of the value to the left by the specified number of bits.

let oldValue = 2;
let newValue = oldValue << 5; / / 64
Copy the code

The binary value of 2 is: 10 moved 5 bits to the left to get: 1000000. This binary number is 64 in decimal.

A left shift preserves the sign of the operand. If I just did minus 2, I get minus 64.

There’s a sign shift to the right

Move the symbol to the right and use >>. It moves all 32 bits to the right while preserving the symbol.

let oldValue = 64; // is equal to binary 1000000
let newValue = oldValue >> 5; / / 5
Copy the code

Unsigned shift to the right

The unsigned right move is represented by >>>. For positive numbers, the operation is the same as a signed right shift. It’s different for negative numbers.

let oldValue = -64; / / equal to binary 11111111111111111111111111000000
let newValue = oldValue >>> 5; // Is equal to the decimal 134217726
Copy the code

This is because the binary representation is 11111111111111111111111111000000-64, moves to the right 5, you get 00000111111111111111111111111110, 134, 217, 726 is converted to a decimal.