Arithmetic shift and logical shift and data type in js

First look at a sample question to help understand

Topic portal
After mastering the idea of ​​the algorithm, writing this question with js will encounter a lot of pitfalls, >> (timeout) and >>> (correct)
The following mainly introduces this problem, which seems simple, in fact, it really involves a lot of things. Look carefully! After reading it, you will have a good grasp of shift operations and js data types.

First explain a few points:
       1. By default, javascript is a signed integer. Note that it is an integer, a total of 32 bits (including the sign bit).
The value range is from -2^31-2^31-1 that is -2147483648 to 2147483647.
        2. javascript uses the actual representation to be stored in 64-bit standard double precision, 1 bit sign bit 11 bit exponent bit 52 mantissa bit.

Let's cut to the main topic:

       For test case 2 -2147483648

       We use the fast exponentiation method to solve, and start to judge if it is a negative number, turn it into a positive number [2^(-3) = 1/(2^3) = (1/2)^3], which is equivalent to finding the positive of its reciprocal Several powers, this should not be difficult for us to understand. The following questions are coming,
       1. Convert -2147483648 to a positive number 2147483648, which exceeds the default signed integer representation range (the default maximum is 2147483647).
           Reason: Although it exceeds the default range, js will automatically convert it to an unsigned integer. Certainly not out of range

(js中的最大最小安全值)
       console.log(Number.MAX_SAFE_INTEGER); //9007199254740991 2^53 -1
       console.log(Number.MIN_SAFE_INTEGER); //-9007199254740991   2^53 -1

2. The next step is the problem of shift operations

        The point is coming!

(1) >>, << means arithmetic shift, the sign bit should be considered when moving (the following examples are the default signed bit, the leftmost bit is the sign bit)
        1101 (-3) Arithmetic right shift by 1 bit 1110 (-2) ; 1101 (-3) Arithmetic shift left by 1 bit 11010 (-6)
        010 (2) Arithmetic shift right by 1 bit 001 (1); 010 (2) Arithmetic shift left by 1 bit 0100 (4);

(2) >>>,<<< means logical shift, overall left and right, missing bits fill 0 (the following examples are the default signed bit, the leftmost bit is the sign bit)
       1101 logical right shift 1 bit 0110; 1101 logical left Shift 1 bit 1010
       010 logic right shift 1 bit 001; 010 logic left shift 1 bit 100;

In the current test case, if you use arithmetic shift, the number converted into a positive number is 2147483648 (exceeding the sign means that it is converted to unsigned by default) is exactly 2^31, (10000……, 31 zeros) the highest bit occupies the sign Bit, in the first cycle, the operation is performed according to the unsigned integer to enter the cycle. When performing the shift operation, if you choose arithmetic shift, the unsigned number will be regarded as a signed number for operation, and the shift After that, n becomes a negative number and exits the loop, so the loop is only performed once in this case. If logical shift is used, this problem will not occur. Of course, the form of Math.floor(n/2) is also equivalent to logical shift, which solves this bug.

Guess you like

Origin blog.csdn.net/qq_44606064/article/details/114698020