Ale*_*pin 178 javascript floating-point bit-manipulation
我的一位同事偶然发现了一种方法来使用按位或者:
var a = 13.6 | 0; //a == 13
Run Code Online (Sandbox Code Playgroud)
我们在谈论它并想知道一些事情.
Math.floor吗?也许它快一点?(双关语不打算)谢谢.
Joe*_*Joe 144
它是如何工作的?我们的理论是使用这样的运算符将数字转换为整数,从而删除小数部分
除了无符号右移之外的所有按位运算都>>>适用于带符号的32位整数.因此,使用按位运算会将float转换为整数.
做Math.floor有什么优势吗?也许它快一点?(双关语不打算)
http://jsperf.com/or-vs-floor/2似乎稍快一些
它有任何缺点吗?也许它在某些情况下不起作用?清晰度是显而易见的,因为我们必须弄清楚,而且,我正在写这个问题.
Math.floor(NaN) === NaN同时(NaN | 0) === 0Cha*_*dia 31
这是截断而不是地板.霍华德的回答是正确的; 但我想补充的Math.floor是,它与负数完全相同.在数学上,这就是一个楼层.
在上面描述的情况下,程序员对截断或完全关闭十进制更感兴趣.虽然,他们使用的语法有点掩盖了他们将float转换为int的事实.
zan*_*ngw 18
在ECMAScript中6,相当于|0是Math.trunc,善良的我应该说:
通过删除任何小数位数返回数字的整数部分.它只是截断点和它后面的数字,无论参数是正数还是负数.
Math.trunc(13.37) // 13
Math.trunc(42.84) // 42
Math.trunc(0.123) // 0
Math.trunc(-0.123) // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN) // NaN
Math.trunc("foo") // NaN
Math.trunc() // NaN
Run Code Online (Sandbox Code Playgroud)
Javascript 表示Number为双精度 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
Run Code Online (Sandbox Code Playgroud)
还。按位运算不“地板”。它们截断,这就是说,它们最接近0。一旦你到处去负数,Math.floor几轮下来,而按位开始舍去了。
正如我之前所说,Math.floor更安全,因为它使用 64 位浮点数运行。按位更快,是的,但仅限于 32 位有符号范围。
总结一下:
0 to 2147483647.-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);
}
Run Code Online (Sandbox Code Playgroud)
只是添加Math.trunc像按位操作一样的工作。所以你可以这样做:
function trunc(n) {
if (n > -0x80000000 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
return Math.trunc(n);
}
Run Code Online (Sandbox Code Playgroud)