Za pomocą bitowego lub 0, aby uzyskać liczbę
Mój kolega natknął się na metodę floatowania liczb używając bitowego or:
var a = 13.6 | 0; //a == 13
Rozmawialiśmy o tym i zastanawialiśmy się nad kilkoma rzeczami.
- Jak to działa? Nasza teoria była taka, że używając takiego operatora rzuca liczbę do liczby całkowitej, usuwając w ten sposób część ułamkową
- czy ma jakąś przewagę nad robieniem
Math.floor
? Może trochę szybciej? (kalambur nieprzeznaczony)
Czy ma jakieś wady? Może w niektórych przypadkach to nie działa? Jasność to oczywiste, ponieważ musieliśmy to rozgryźć, I cóż, piszę to pytanie.
6 answers
Jak to działa? Nasza teoria głosiła, że użycie takiego operatora powoduje Liczba do liczby całkowitej, usuwając w ten sposób część ułamkową
Wszystkie operacje bitowe z wyjątkiem unsigned right shift, >>>
, działają na podpisanych 32-bitowych liczbach całkowitych. Użycie operacji bitowych przekonwertuje zmiennoprzecinkowy na liczbę całkowitą.
Czy to ma jakąś przewagę nad matematyką.podłoga? Może to trochę szybciej? (kalambur nieprzeznaczony)
Http://jsperf.com/or-vs-floor/2 wydaje się nieco szybciej
Czy ma jakieś wady? Może w niektórych przypadkach to nie działa? Klarowność jest oczywista, ponieważ musieliśmy to rozgryźć i dobrze, Piszę to pytanie.
- nie przejdzie jsLint.
- tylko liczby całkowite z podpisem 32-bitowym
- dziwne zachowanie porównawcze:
Math.floor(NaN) === NaN
, natomiast(NaN | 0) === 0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-02 03:32:07
To jest obcinanie w przeciwieństwie do podłogi. Odpowiedź Howarda jest w pewnym sensie poprawna, ale dodam, że Math.floor
robi dokładnie to, co powinno w odniesieniu do liczb ujemnych. Matematycznie, tym jest Podłoga.
W opisanym powyżej przypadku programista był bardziej zainteresowany okrojeniem lub całkowitym odcięciem dziesiętnym. Chociaż składnia, której używali, zasłania fakt, że konwertują float na int.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-20 15:54:29
W ECMAScript 6 odpowiednikiem |0
jest Matematyka.trunc , rodzaj powinienem powiedzieć:
Zwraca całkę liczby, usuwając dowolne cyfry ułamkowe. Po prostu obcina kropkę i cyfry za nią, bez względu na to, czy argument jest liczbą dodatnią, czy ujemną.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-10 13:44:55
Twój pierwszy punkt jest poprawny. Liczba jest rzucana do liczby całkowitej, a zatem wszelkie cyfry dziesiętne są usuwane. Należy pamiętać, że Math.floor
zaokrągla do następnej liczby całkowitej w kierunku minus nieskończoności, a tym samym daje inny wynik w przypadku liczb ujemnych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-20 15:51:51
-
Specyfikacja mówi, że jest przekonwertowana na liczbę całkowitą:
Niech lnum będzie ToInt32 (lval).
Wydajność: to zostało przetestowane w jsperf wcześniej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-20 16:54:52
Javascript reprezentuje Number
jako 64-bitowe liczby zmiennoprzecinkowe o podwójnej precyzji.
Math.floor
działa z tym w umyśle.
Operacje bitowe działają w 32bitach podpisanych liczbach całkowitych. 32-bitowe liczby całkowite używają pierwszego bitu jako znaku ujemnego, a pozostałe 31 bitów to liczba. Z tego powodu liczba min i max dozwolonych 32-bitowych podpisanych numerów to odpowiednio -2,147,483,648 i 2147483647 (0x7FFFFFFFF).
Więc kiedy robisz | 0
, jesteś zasadniczo robi to & 0xFFFFFFFF
. Oznacza to, że każda liczba reprezentowana jako 0x80000000 (2147483648) lub większa powróci jako liczba ujemna.
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 "podłoga". Oniobcinają , co jest tym samym, co powiedzenie, zaokrąglają się najbliżej 0
. Gdy przejdziesz do liczb ujemnych, Math.floor
zaokrągla w dół podczas bitowego zaokrąglania w górę.
Jak już mówiłem, Math.floor
jest bezpieczniejsze, ponieważ działa z 64-bitowymi liczbami zmiennymi. Bitowe jest szybsze, tak, ale ograniczone do zakresu 32-bitowego.
Do podsumowania:
- bitowe działa tak samo, jeśli pracujesz z
0 to 2147483647
. - bitowe jest 1 Liczba wyłączona, jeśli pracujesz z
-2147483647 to 0
. - bitowy jest zupełnie inny dla liczb mniejszych niż
-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);
}
Wystarczy dodać Math.trunc
działa jak operacje bitowe. Więc możesz to zrobić:
function floor(n) {
if (n > -0x80000000 && n < 0x80000000) {
return n & 0xFFFFFFFF;
}
return Math.trunc(n);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-04 15:39:03