JavaScript reprezentuje Number
jako zmiennoprzecinkowe liczby 64-bitowe Double Precision .
Math.floor
działa z tą myślą.
Operacje bitowe działają w 32-bitowych podpisane liczb całkowitych. 32-bitowe liczby całkowite ze znakiem używają pierwszego bitu jako ujemnego znacznika, a pozostałe 31 bitów to liczba. Z tego powodu, minimalna i maksymalna liczba dozwolonych 32-bitowych liczb ze znakami wynosi odpowiednio -2 147 483 648 i 2147483647 (0x7FFFFFFFF).
Więc kiedy to robisz | 0
, zasadniczo to robisz & 0xFFFFFFFF
. Oznacza to, że każda liczba reprezentowana jako 0x80000000 (2147483648) lub wyższa zwróci liczbę ujemną.
Na przykład:
// 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
Również. Operacje bitowe nie „piętrzą”. Oni obciąć , który jest taki sam jak powiedzenie, że zaokrąglanie najbliżej 0
. Po przejściu do liczb ujemnych Math.floor
zaokrągla się w dół, a bitowe zaczyna zaokrąglać w górę .
Jak powiedziałem wcześniej, Math.floor
jest bezpieczniejszy, ponieważ działa z liczbami zmiennoprzecinkowymi 64-bitowymi. Bitowe jest szybsze , tak, ale ograniczone do 32-bitowego podpisanego zakresu.
Podsumowując:
- Bitowe działa tak samo, jeśli pracujesz z
0 to 2147483647
.
- Bitowa to 1 liczba wyłączona, jeśli pracujesz z
-2147483647 to 0
.
- Bitowa jest zupełnie inna dla liczb mniejszych
-2147483648
i większych niż 2147483647
.
Jeśli naprawdę chcesz poprawić wydajność i użyć obu:
function floor(n) {
if (n >= 0 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
if (n > -0x80000000 && n < 0) {
return (n - 1) & 0xFFFFFFFF;
}
return Math.floor(n);
}
Tylko dodanie Math.trunc
działa jak operacje bitowe. Możesz to zrobić:
function trunc(n) {
if (n > -0x80000000 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
return Math.trunc(n);
}