在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。
我真的好奇为什么会发生这些现象?是否有任何规范或理论可以解释这些奇怪的行为?
答案 0 :(得分:5)
来自MDN:
所有位运算符的操作数都以二进制补码格式转换为带符号的32位整数。
JavaScript中的所有数字均为IEEE754 double precision floating point numbers。在应用按位运算符之前,它们被转换为32位整数。
更准确地说,此过程在ToInt32 in the spec:
中有所描述
如您所见,精确描述了无穷大和-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 == 410065408说明了模块化代数的用法。
这两种方式都有效:inf&lt;&lt; inf等于0 <&lt;&lt; 0
答案 2 :(得分:0)
根据ECMA-262。
基本上,JS编译器使用ECMA-262第9.5项中描述的算法将浮点参数转换为32位整数。在大多数情况下,您提到转换结果为0.