1

查看以下示例,它看起来Math.floor(x)相当于x | 0, for 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).

4

5 回答 5

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

于 2012-02-22T09:22:41.027 回答
4

根据ECMAScript 规范,§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然后将|运算符应用于它们。

于 2012-02-22T09:25:42.380 回答
3

JS 中的按位运算是 32 位的,即浮点数首先“转换”为“int”。

"2.6" | 0 = 2表明parseInt正在调用。

于 2012-02-22T09:22:10.787 回答
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
于 2012-02-22T09:20:15.163 回答
1

(x | 0) 删除“.”之后的位,因此我们可以得到下一个真正的关系:

x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;

x >> 0 与 x | 具有相同的效果 0,所以:

x >> 0 = x | 0 = (x < 0 ? -1 : 1) * Math.floor(Math.abs(x)) ;
于 2012-02-22T09:11:46.607 回答