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

时间:2015-06-05 18:05:02

标签: javascript bitwise-operators

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

常见案例

1 << 0            // returns 1, makes sense
100 << 0          // returns 100, makes sense
100 >> 0          // returns 100, definitely makes sense

但是这些,当移位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

如果无限和按位移动

,该怎么办?
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

上述情况对我来说没什么意义。 当将整数移位0位时,该值不会改变 但是当你将Infinity移动0位时,它实际上会返回0 。为什么呢?

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

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

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

3 个答案:

答案 0 :(得分:5)

来自MDN:

  

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

JavaScript中的所有数字均为IEEE754 double precision floating point numbers。在应用按位运算符之前,它们被转换为32位整数。

更准确地说,此过程在ToInt32 in the spec

中有所描述

enter image description here

如您所见,精确描述了无穷大和-0的转换。

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

答案 1 :(得分:3)

JavaScript中的位移和逻辑运算被评估为32位整数。存在&lt;&lt;如果转换失败,operator需要将任何对象转换为int或0。无穷大或99e9是有效的ieee双倍,但无法转换为int:9e99 mod 2 ^ 32 == 0.计数器示例9e9 | 0 == 41006540​​8说明了模块化代数的用法。

这两种方式都有效:inf&lt;&lt; inf等于0 <&lt;&lt; 0

答案 2 :(得分:0)

根据ECMA-262

基本上,JS编译器使用ECMA-262第9.5项中描述的算法将浮点参数转换为32位整数。在大多数情况下,您提到转换结果为0.