查看以下示例,对于Math.floor(x)
,x | 0
看起来等同于x >= 0
。这是真的吗?如果是,为什么? (或如何计算x | 0
?)
x = -2.9; console.log(Math.floor(x) + ", " + (x | 0)); // -3, -2
x = -2.3; console.log(Math.floor(x) + ", " + (x | 0)); // -3, -2
x = -2; console.log(Math.floor(x) + ", " + (x | 0)); // -2, -2
x = -0.5; console.log(Math.floor(x) + ", " + (x | 0)); // -1, 0
x = 0; console.log(Math.floor(x) + ", " + (x | 0)); // 0, 0
x = 0.5; console.log(Math.floor(x) + ", " + (x | 0)); // 0, 0
x = 2; console.log(Math.floor(x) + ", " + (x | 0)); // 2, 2
x = 2.3; console.log(Math.floor(x) + ", " + (x | 0)); // 2, 2
x = 2.9; console.log(Math.floor(x) + ", " + (x | 0)); // 2, 2
x = 3.1; console.log(Math.floor(x) + ", " + (x | 0)); // 3, 3
这对于在Javascript中执行整数除法非常有用:(5 / 3) | 0
而不是Math.floor(5 / 3)
。
答案 0 :(得分:4)
按位运算符将数字转换为32位序列。因此,您建议的替代方案仅适用于带正号的32位浮点数,即从0
到+2,147,483,647
(2^31-1
)的数字。
Math.floor(2147483646.4); // 2147483647
2147483646.4 | 0; // 2147483647
// but…
Math.floor(2147483648.4); // 2147483648
2147483648.4 | 0; // -2147483648
另一个区别:如果x
不是数字,则x | 0
的结果可能与Math.floor(x)
的结果不同。
Math.floor(NaN); // NaN
NaN | 0; // 0
除此之外,只要使用正数,结果应与Math.floor()
的结果类似。
以下是更多示例+效果测试:http://jsperf.com/rounding-numbers-down
答案 1 :(得分:3)
根据ECMAScript spec,§11.10二进制位运算符:
Semantics
The production A : A @ B, where @ is one of the bitwise operators in the productions
above, is evaluated as follows:
1. Let lref be the result of evaluating A.
2. Let lval be GetValue(lref).
3. Let rref be the result of evaluating B.
4. Let rval be GetValue(rref).
5. Let lnum be ToInt32(lval).
6. Let rnum be ToInt32(rval).
7. Return the result of applying the bitwise operator @ to lnum and rnum. The result
is a signed 32 bit integer.
这是计算x | y
的方式:
x
和y
已解析为Int32
,然后将|
运算符应用于它们。
答案 2 :(得分:2)
垂直条是按位或运算符。由于0的位都是零,因此x|0
在理论上是无操作。但是为了评估它,操作数必须是整数,因此x
必须首先从浮点转换为整数。转换是通过消除小数部分来实现的,所以是的,对于某些x> = 0,我们有x|0
== Math.floor(x)
。
请注意,结果取决于内部整数类型的大小和符号。例如,你得到:
2147483648|0 == -2147483648 // 0x80000000
Math.pow(2,32)|0 == 0 // the lowest 32 bits are all 0
答案 3 :(得分:2)
JS中的按位运算是32位,即浮点数首先被“转换”为“int”。
"2.6" | 0 = 2
表示正在调用parseInt
。
答案 4 :(得分:1)
(x | 0)删除“。”之后的位,因此我们可以获得下一个真正的关系:
x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;
x&gt;&gt; 0与x |具有相同的效果0,所以:
x >> 0 = x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;