An overview of the

Binary operators are used to evaluate binary bits directly, and there are seven of them.

  • Binary or operator(or) : the symbol is|, if both bits are0, the result is0, or for1.
  • Binary and operators(and) : the symbol is&If both bits are 1, the result is 1; otherwise, the result is 0.
  • Binary no operator(not) : the symbol is~Represents the inverse of a binary bit.
  • Xor operator(xor) : symbol is^If the two bits are different, the result is 1; otherwise, the result is 0.
  • Left shift operator(left shift) : symbol is<<, see the explanation below.
  • Right shift operator(right shift) : the symbol is>>, see the explanation below.
  • The right shift operator for header zeroing(Zero filled right Shift) : the symbol is>>>, see the explanation below.

These bitwise operators deal directly with each bit, so they are very low-level operations. The advantage is that they are extremely fast, but the disadvantage is that they are very unintuitive and cannot be used in many situations, otherwise the code will be difficult to understand and check for errors.

It is important to note that bitwise operators only work on integers. If an operator is not an integer, it is automatically converted to an integer before being executed. In addition, although values are stored as 64-bit floating-point numbers inside JavaScript, bitwise operations are performed as 32-bit signed integers and the return value is a 32-bit signed integer.

i = i | 0;
Copy the code

The above line of code means converting I (whether integer or decimal) to a 32-bit integer.

Using this feature, you can write a function that converts any value to a 32-bit integer.

function toInt32(x) {
  return x | 0;
}
Copy the code

The above function performs an or on any value with 0. This bit operation automatically converts a value to a 32-bit integer. Here is how this function is used.

ToInt32 (1.001) // 1 toInt32(1.999) // 1 toInt32(1) // 1 toInt32(-1) // -1 toInt32(math.pow (2, Math. 32) + 1) // 1 toInt32(Math.pow(2, 32) - 1) // -1Copy the code

In the code above, toInt32 converts a decimal to an integer. For normal integers, the return value does not change at all. For integers greater than or equal to 2 to the 32 power, bits greater than 32 are omitted.

Binary or operator

Binary or operator (|) bit by bit compare two operator command, as long as there is one of two binary is 1, it returns 1, otherwise it returns 0.

0 | 3 / / 3Copy the code

In the code above, the binary forms of 0 and 3 are 00 and 11, respectively, so binary or yields 11 (i.e., 3).

The bitwise operation is valid only for integers. When a decimal is encountered, the decimal part is discarded and only the integer part is retained. Therefore, binary or of a decimal with 0 is equivalent to dividing the decimal part of the number, that is, taking the integer bits.

2-2.9 | | 0/2.9/0 / / - 2Copy the code

Note that this rounding method does not apply to numbers that exceed the maximum value of a 32-bit integer, 2147483647.

2147483649.4 | 0; / / - 2147483647Copy the code

Binary and operators

The rule for the binary and operator (&) is to compare two operators bit by bit, returning 0 as long as one of the binary bits is 0, and 1 otherwise.

0 &3 // 0Copy the code

In the code above, binary sums of 0 (binary 00) and 3 (binary 11) yield 00 (i.e., 0).

Binary no operator

The binary no operator (~) changes each binary bit to the opposite value (0 to 1,1 to 0). Its return is sometimes difficult to understand because of the numerical representation mechanism inside the computer.

~ 3 // -4
Copy the code

The above expression applies binary no to 3 to get -4. This result occurs because when bitwise operations are performed, JavaScript internally converts all operators to 32-bit binary integers.

Three forms of 32-bit integer is 00000000000000000000000000000011, whether the binary operation after 11111111111111111111111111111100. Since the first digit is 1, the number is a negative number. JavaScript internally uses the form of complement to represent negative numbers, which means that you need to subtract 1 from the number, negate it again, and then add a negative sign to get the corresponding decimal value. This number minus 1 equals 11111111111111111111111111111011, get 00000000000000000000000000000100, take again the plus minus sign is – 4. And since it’s a little bit of a hassle to do that, you can just remember that if you add something to its negative value, it’s equal to negative 1.

~ -3 // 2
Copy the code

So this expression up here, the inverse of negative 3 is equal to negative 1 minus negative 3, which is 2.

Operation on an integer twice in a row to get itself.

~ ~ 3 / / 3Copy the code

All bit operations are valid only for integers. When the binary no operation encounters a decimal, the decimal part will be omitted and only the integer part will be retained. Therefore, two consecutive binary no operations on a decimal can achieve the rounding effect.

~~2.9 // 2 ~47.11 // 47 ~1.9999 // 1 ~3 // 3Copy the code

Integer using binary no operation is the fastest of all integer methods.

To perform binary negation on a string, the JavaScript engine first calls the Number function to convert the string to a Number.

/ / equivalent to ~ Number (' 011 ') - '011' / / / / equivalent to 12 ~ Number () '42 cats' ~' 42 cats' / / / / - 1 is equivalent to the Number (' 0 xcafebabe) ~ '0 xcafebabe' // 889275713 // equivalent to ~Number('deadbeef') ~'deadbeef' // -1Copy the code

For the rules for the Number function to convert a string to a Number, see the chapter on Data Type Conversion.

For other types of values, the binary no operation also converts Number to a Number and then processes it.

/ / equivalent to ~ Number ([]) to [] / / / / - 1 is equivalent to Number (NaN) - NaN / / / / - 1 is equivalent to Number (null) to null / / 1Copy the code

Xor operator

The xor operation (^) returns 1 if the two bits are different and 0 if the two bits are identical.

0 ^ 3 / PI / 3Copy the code

In the above expression, 0 (binary 00) and 3 (binary 11) perform xOR, each of which is different, resulting in 11 (that is, 3).

A special use of “xOR” is to perform three consecutive xOR operations on two numbers a and b, a^=b; b^=a; a^=b; And you can swap their values. This means that xOR can be used to swap the values of two variables without introducing temporary variables.

var a = 10;
var b = 99;

a ^= b, b ^= a, a ^= b;

a // 99
b // 10
Copy the code

This is the fastest way to interchange the values of two variables.

Xor operations can also be used to round.

12.9 ^ 0 // 12
Copy the code

Left shift operator

The left-shift operator (<<) moves the binary value of a number to the left by a specified number of digits, terminating with 0, multiplied by 2 to the specified power. When you move to the left, the highest sign bit moves together.

// The binary form of 4 is 100, and // moving one bit to the left is 1000 (i.e. decimal 8) // is equivalent to multiplying 2 to the first power 4 << 1 // 8-4 << 1 // -8Copy the code

The above code, – 4 left a get – 8, because binary form is 11111111111111111111111111111100-4, left a after 11111111111111111111111111111000, the number to a decimal (minus 1 after the, Plus the minus sign is minus 8.

If you move 0 bits to the left, you convert the value to a 32-bit integer, which is the same as a round, for both positive and negative numbers.

13.5 << 0 // 13-13.5 << 0 // -13Copy the code

The left-shift operator is handy for binary values.

var color = {r: 186, g: 218, b: 85}; Var rgb2hex = function(r, g, 0); B) {return '#' + (24) + (r (1 < < < < 16) + (g < < 8) + b). ToString (16) / / convert hexadecimal first, and then returns a string. The substr (1); } rgb2hex(color.r, color.g, color.b) // "#bada55"Copy the code

The code above converts the RGB value of the color to HEX using the left-shift operator.

Right shift operator

The right-shift operator (>>) moves the binary value of a number to the right by a specified number of digits. If it’s positive, add zeros to all the heads; If it’s negative, add 1’s to all the heads. The right-shift operator is basically equivalent to dividing by 2 to the specified power (the highest bit, the sign bit, is involved in the move).

4 > > 1/2 / * / / / because of 4 binary form for 00000000000000000000000000000100, / / moves to the right one, you get 00000000000000000000000000000010 2 * / / / is the decimal - 4 > > 1/2 / * / / / - for binary form for 11111111111111111111111111111100-4, / / moves to the right one, head to fill 1, 11111111111111111111111111111110 / /, which is a decimal - 2 * /Copy the code

The right shift can simulate the exact division of 2.

5 >> 1 // 2 // equivalent to 5/2 = 2 21 >> 2 // 5 // equivalent to 21/4 = 5 21 >> 3 // 2 // equivalent to 21/8 = 2 21 >> 4 // 1 // equivalent to 21/16 =  1Copy the code

The right shift operator for header zeroing

The only difference between the right shift operator (>>>) and the right shift operator (>>) is that when the binary form of a number moves to the right, the head is filled with zeros regardless of the sign bit. So, the operation always gets a positive value. For positive numbers, the result of this operation is exactly the same as the right-shift operator (>>), except for negative numbers.

4 > > > 1 / / 2-4 > > > 1 / / 2147483646 / * / / for binary form for 11111111111111111111111111111100-4, / / take the sign bit moves to the right one, 01111111111111111111111111111110 / /, which is a decimal 2147483646. * /Copy the code

This operation actually converts a value to a 32-bit unsigned integer.

The fastest way to see how a negative integer is stored inside a computer is to use this operator.

-1 >>> 0 // 4294967295
Copy the code

Code above, said – 1 as a 32-bit integer, the storage form of internal use unsigned integer format, value is 4294967295 (namely (2 ^ 32) – 1, equal to 11111111111111111111111111111111).

Switch function

Bitwise operators can be used as switches to set object properties.

Suppose an object has four switches, each of which is a variable. So, you can set up a four-bit binary number, each of which corresponds to a switch.

var FLAG_A = 1; // 0001 var FLAG_B = 2; // 0010 var FLAG_C = 4; // 0100 var FLAG_D = 8; / / 1000Copy the code

The above code sets A, B, C, D four switches, each switch occupies A binary bit.

You can then use binary and operations to check whether the specified switch is turned on in the current setting.

var flags = 5; If (flags & FLAG_C) {//... } // 0101 & 0100 => 0100 => trueCopy the code

The code above checks to see if switch C is turned on. Returns true if enabled, false otherwise.

Now, assuming we need to turn on switches A, B, and D, we can construct A mask variable.

var mask = FLAG_A | FLAG_B | FLAG_D; / / 0001 | 0010 | 1000 = > 1011Copy the code

The above code performs binary or operation on variables A, B and D to obtain 1011 with binary mask value.

With masks, binary or operations ensure that the specified switch is turned on.

flags = flags | mask;
Copy the code

In the code above, the computed flags variable indicates that the binary bits of all three switches are on.

Binary and operation can turn off all items in the current Settings that are different from the switch Settings.

flags = flags & mask;
Copy the code

The xOR operation toggles the current setting the first time to get the opposite value and the second time to get the same value again.

flags = flags ^ mask;
Copy the code

Binary No operation can reverse the current setting, that is, the original setting is 0, after operation to 1; It was set to 1, but changed to 0 after calculation.

flags = ~flags;
Copy the code