Javascript Integer Division,或者是Math.floor(x)等效于x | 0表示x> = 0?

时间:2012-02-22 08:56:44

标签: javascript division integer-division

查看以下示例,对于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)

5 个答案:

答案 0 :(得分:4)

按位运算符将数字转换为32位序列。因此,您建议的替代方案仅适用于带正号的32位浮点数,即从0+2,147,483,6472^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的方式:     xy已解析为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)) ;