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
また。ビット演算は「フロア」ではありません。彼らは切り捨てます。これは言うのと同じで、に最も近い丸め0
です。あなたが負の数に回るたら、Math.floor
ラウンドダウンながら、ビット単位で丸め開始アップ。
前に述べたように、Math.floor
64ビット浮動小数点数で動作するため、より安全です。ビットワイズの方が高速ですが、32ビットの符号付きスコープに制限されています。
要約する:
- から作業する場合、ビットワイズは同じように機能し
0 to 2147483647
ます。
- から作業する場合、ビットワイズは1オフです
-2147483647 to 0
。
- Bitwiseは、より小さい
-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);
}