We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MDN解释
移位表达式 << 加法表达式
0 << 1 // 0 --> 0 * (2 ** 1) 1 << 1 // 2 --> 1 * (2 ** 1) 2 << 1 // 4 --> 2 * (2 ** 1) 3 << 1 // 6 --> 3 * (2 ** 1) 4 << 1 // 8 --> 4 * (2 ** 1) -1 << 1 // -2 --> -1 * (2 ** 1) 1 << 10 // 1024 --> 1 * (2 ** 10) true << 1 // 1 --> 1 * (2 ** 1) false << 1 // 0 --> 0 * (2 ** 1) null << 1 // 0 undefined << 1 // 0 NaN << 1 // 0 Infinity << 1 // 0 -Infinity << 1 // 0 [] << 1 // 0 [{}] << 1 // 0 9n << 1 // 报错 Number(9n) << 1 // 18 --> 9 * (2 ** 1) '' << 1 // 0 --> 0 * (2 ** 1) 先把字符串转为Number
左移运算,把运算符右边的数值看成 幂(也是数学上常说的次方),基数是 2,可以看成 运算符左边的数值 * (2 ** 运算符右边的数值)。运算符左边会先转换成数值,注意这里不是简单的 ToNumber,左边执行的是 ToInt32,所以undefined之类能转成0。
运算符左边的数值 * (2 ** 运算符右边的数值)
undefined
运算符右边如果不是BigInt,那么会执行 ToUint32 转换
移位表达式 >> 加法表达式
0 >> 0 // 0 0 >> 1 // 0 99 >> 0 // 99 1 >> 1 // 0 2 >> 1 // 1 3 >> 1 // 1 4 >> 1 // 2 1 >> 2 // 0 2 >> 2 // 0 3 >> 2 // 0 4 >> 2 // 1 8 >> 2 // 2 true >> 0 // 1 true >> 1 // 0 false >> 1 // 0 null >> 1 // 0 undefined >> 1 // 0 NaN >> 1 // 0 '' >> 1 // 0 'adadfsfs' >> 1 // 0 [] >> 1 // 0 [{}] >> 1 // 0 Number(2n) >> 1 // 1 Infinity >> 1 // 0 -Infinity >> 1 // 0 -9 >> 1 // -5 9 >> 1 // 4
运算符左边如果不是BigIng,会执行 ToInt32 转换;运算符右边如果不是BigInt,那么会执行 ToUint32 转换
这里懂点需要点二进制知识,以上面示例代码 2 >> 1 为例:
2 >> 1
// 2 在运算符左边,执行 ToInt32(2) 转换成32位有符号二进制整数,对应上述算法的 lnum,即 00000000 00000000 00000000 00000010 // 1 在运算符右边,执行 ToUint32(1) 转换成32位无符号二进制整数,对应上述算法的 rnum,即 00000000 00000000 00000000 00000001 // 根据 Number::signedRightShift 算法 执行 rnum & 0x1F 按位与运算,即 00000000 00000000 00000000 00000001 & 00000000 00000000 00000001 11111111 // 得到 shiftCount 二进制形式 00000000 00000000 00000000 00000001 // 然后对 lnum 右移 shiftCount 位,其实就是右移 1 位, // 对 00000000 00000000 00000000 00000010 右移一位,最右边的一位这里是0,丢掉,左边最高位补个0,得到 00000000 00000000 00000000 00000001 // 最终转换为十进制,得到 1
为何 9 >> 1 是 4,而 -9 >> 1 是 -5 呢?为何不是 -4?
9 >> 1
-9 >> 1
// 先对 -9 进行二进制转换,这里需要转换成有符号的32位二进制整数 // 先转 9,得到 00000000 00000000 00000000 00001001 // 取其反码 11111111 11111111 11111111 11110110 // + 1,得到 -9 对应的32位有符号二进制数 11111111 11111111 11111111 11110111 // 然后右移 1 位,得到 11111111 11111111 11111111 11111011 // 这是补码形式,我需要转换成其正数形式得到对应的十进制整数, // 那么此时要先 - 1 得到反码 11111111 11111111 11111111 11111010 // 反码转换成正常码 00000000 00000000 00000000 00000101 // 对应十进制正数 5,但是其实我得到的是负数,只是为了获取十进制所以进行了逆推 // 所以实际上最终结果是 -5
移位表达式 >>> 加法表达式
0 >>> 0 // 0 0 >>> 1 // 0 1 >>> 0 // 1 2 >>> 0 // 2 1 >>> 1 // 0 2 >>> 1 // 1 3 >>> 1 // 1 4 >>> 1 // 2 5 >>> 1 // 2 6 >>> 1 // 3 1 >>> 2 // 0 2 >>> 2 // 0 4 >>> 2 // 1 true >>> 0 // 1 true >>> 1 // 0 false >>> 0 // 0 null >>> 0 // 0 null >>> 1 // 0 undefined >>> 0 // 0 undefined >>> 1 // 0 NaN >>> 1 // 0 '' >>> 1 // 0 'adadfsfs' >>> 1 // 0 [] >>> 1 // 0 [{}] >>> 1 // 0 Number(2n) >>> 1 // 1 Infinity >>> 1 // 0 -Infinity >>> 1 // 0 -1 >>> 0 // 4294967295 -1 >>> 1 // 2147483647
为何 -1 >>> 0 结果是 4294967295?
-1 >>> 0
4294967295
// 首先明确这里是无符号右移运算,32位无符号整数范围是 0 ~ (2 ** 32) - 1 // 1 对应的码是 00000000 00000000 00000000 00000001 // 其反码 11111111 11111111 11111111 11111110 // 其补码 11111111 11111111 11111111 11111111 // 右移 0 位,按道理是 11111111 11111111 11111111 11111111 // 可是这里不能为负,只能是正数,这个数刚好是 (2 ** 32) - 1 即 4294967295 // -1 >>> 1 右移1位,由于无符号右移, // 所以最高位只能补0,不能补1, // 最高位补 0 为正,最高位补 1 为负 // 所以 -1 >>> 1 得到的是 01111111 11111111 11111111 11111111 // 即 2147483647
The text was updated successfully, but these errors were encountered:
很棒,有参考价值,多谢
Sorry, something went wrong.
No branches or pull requests
按位移位运算符
一、左移运算符 (<<)
MDN解释
移位表达式 << 加法表达式
二、带符号的右移运算符 (>>)
MDN解释
移位表达式 >> 加法表达式
这里懂点需要点二进制知识,以上面示例代码
2 >> 1
为例:为何
9 >> 1
是 4,而-9 >> 1
是 -5 呢?为何不是 -4?三、无符号右移运算符 (>>>)
MDN解释
移位表达式 >>> 加法表达式
为何
-1 >>> 0
结果是4294967295
?The text was updated successfully, but these errors were encountered: