所以我试图在javascript中制作一些函数来移位和操纵数字位。但是,我在控制台中发现以下行为
> var a = 1;
undefined
> a <<= 3
8
> a <<= 55
67108864
> a <<= 40
0
我的问题是,如果该值大于某个点,为什么该数字又回到零?在其他语言(例如python)中,数字只会越来越大,或者使用符号来保存数字的值。或者,显示溢出错误。为什么JavaScript会将数字简单地重置为零?
答案 0 :(得分:4)
Shift运算符将其操作数按big-endian顺序转换为32位整数,并返回与左操作数相同类型的结果。正确的操作数应小于32,但如果不只使用低5位。
因此,对于您的55 (0x110111)
和40 (0x101000)
,您分别进行了23 (0x10111)
和8 (0x01000)
的位移:
> var a = 1;
undefined
> a <<= 3
8
> a <<= 23
67108864
> a <<= 8
0
请注意,尽管这些与您编写的内容不同,但是答案与获得0的原因相同,请考虑以下位:
> var a = 1;
undefined
> a <<= 3 + 23
67108864 // 0x000[00000100000000000000000000000000]
> a <<= 8
0 // 0x100[00000000000000000000000000000000]
方括号表示实际用于确定数字值的值,左侧的部分被舍弃。如您所见,您已经将数字1移到了数字的左侧,结果剩下了0。
请注意以下代码段,在达到32个移位标记后,所有结果均为0:
var a = 1;
for(var i = 1; i < 40; i++){
a <<= 1;
console.log(i, a);
}
答案 1 :(得分:0)
在ES2018 section 12.9.3.1中定义了左移的语义。主要要了解的是,左操作数被强制转换为32位带符号整数,结果也是32位整数。
向左移位时,左操作数将移位由右操作数(的最低5位)指定的位数。
例如,1 << 3
是执行二进制转换
00000000000000000000000000000001
到
00000000000000000000000000001000
即8
。
操作67108864 << 40
(与操作67108864 << 8
相同)在32位数字上操作
00000100000000000000000000000000
当您将其向上移动八位时,您最终会得到
10000000000000000000000000000000000
这是35位。由于移位的输出始终是一个有符号的32位数字,因此它丢失了它们的最高位,从而导致较低的32位表示0
。