如果位数移位过多,则Javascript编号将重置为0

时间:2018-07-17 16:37:01

标签: javascript bit-manipulation

所以我试图在javascript中制作一些函数来移位和操纵数字位。但是,我在控制台中发现以下行为

> var a = 1;
undefined
> a <<= 3
8
> a <<= 55
67108864
> a <<= 40
0

我的问题是,如果该值大于某个点,为什么该数字又回到零?在其他语言(例如python)中,数字只会越来越大,或者使用符号来保存数字的值。或者,显示溢出错误。为什么JavaScript会将数字简单地重置为零?

2 个答案:

答案 0 :(得分:4)

根据the documentation

  

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