Javascript表示Number
为Double Precision 64位浮点数。
Math.floor
考虑到这一点。
按位运算以32位带符号整数工作。32位带符号整数将第一位用作负号,其他31位为数字。因此,允许的最小和最大数字32位带符号数字分别为-2,147,483,648和2147483647(0x7FFFFFFFF)。
所以当你做的时候| 0
,本质上你就是在做& 0xFFFFFFFF
。这意味着,任何表示为0x80000000(2147483648)或更大的数字都将作为负数返回。
例如:
// Safe
(2147483647.5918 & 0xFFFFFFFF) === 2147483647
(2147483647 & 0xFFFFFFFF) === 2147483647
(200.59082098 & 0xFFFFFFFF) === 200
(0X7FFFFFFF & 0xFFFFFFFF) === 0X7FFFFFFF
// Unsafe
(2147483648 & 0xFFFFFFFF) === -2147483648
(-2147483649 & 0xFFFFFFFF) === 2147483647
(0x80000000 & 0xFFFFFFFF) === -2147483648
(3000000000.5 & 0xFFFFFFFF) === -1294967296
也。按位操作不会“落地”。它们截断,这与说的一样,它们最接近0
。一旦你到处去负数,Math.floor
几轮下来,而按位开始舍去了。
就像我之前说的那样,Math.floor
它更安全,因为它使用64位浮点数。按位速度更快,是的,但仅限于32位带符号范围。
总结一下:
- 如果从开始工作,则按位工作原理相同
0 to 2147483647
。
- 如果您从开始工作,则按位计算将减少1
-2147483647 to 0
。
- 对于小于
-2147483648
和大于的数字,按位运算完全不同2147483647
。
如果您真的想调整性能并同时使用两者:
function floor(n) {
if (n >= 0 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
if (n > -0x80000000 && n < 0) {
return (n - 1) & 0xFFFFFFFF;
}
return Math.floor(n);
}
只是添加Math.trunc
像按位运算的作品。因此,您可以执行以下操作:
function trunc(n) {
if (n > -0x80000000 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
return Math.trunc(n);
}