为什么在JavaScript中使用0进行逐位移位会在某些情况下产生奇怪的结果

Tao*_*oPR 4 javascript bitwise-operators

刚刚在JavaScript中使用了不寻常的按位操作,在某些情况下我得到了一些奇怪的结果:

通常情况

1 << 0            // returns 1, makes sense
100 << 0          // returns 100, makes sense
100 >> 0          // returns 100, definitely makes sense
Run Code Online (Sandbox Code Playgroud)

但是这些,当移位0位时,所有产生零

9E99 << 0         // returns 0 ..... Why all bits are cleared?
9E99 >> 0         // returns 0 also  ..... All bits cleared?
Infinity >> 0     // returns 0
Infinity << 0     // returns 0
-Infinity << 0    // returns 0 .... Can't explain why
-0 << 0           // also yields 0 not -0 itself
-0 >> 0           // also resolved to 0
Run Code Online (Sandbox Code Playgroud)

如果无限和按位移动怎么办?

1 << Infinity     // returns 1  .. no changes
1024 << Infinity  // returns 1024 .. no changes
1024 >> Infinity  // returns 1024 .. no changes either
Infinity >> Infinity      // 0
Infinity << Infinity      // 0
Run Code Online (Sandbox Code Playgroud)

上面的那些案例对我来说没有多大意义.将整数移位0位时,该值不会更改.但是当你移位Infinity0位时,它实际上会返回0.为什么?

我认为将任何数值移位0位不应该改变它的值,不是吗?

此外,当将小整数值移位无穷大位时,该值根本不会改变.但是,当您将Infinity移动任何值时,它将替换为0.

我真的好奇为什么会发生这些现象?是否有任何规范或理论可以解释这些奇怪的行为?

Den*_*ret 5

来自MDN:

所有位运算符的操作数都以二进制补码格式转换为带符号的32位整数.

JavaScript中的所有数字都是IEEE754双精度浮点数.在应用按位运算符之前,它们被转换为32位整数.

更准确地说,此过程在规范中的ToInt32有所描述:

在此输入图像描述

如你所见,无限的转型-0正是如此.

这是一个二进制截断,它也解释了为什么9E99变成0:如果你看一下右边的32位,这是最明显的(9E99).toString(2)(将它粘贴到你的控制台中,它们都是0).