Ein Kollege von mir stieß auf eine Methode, um Float-Zahlen mit einem bitweisen oder:
var a = 13.6 | 0; //a == 13
Wir haben darüber gesprochen und uns ein paar Dinge gefragt.
- Wie funktioniert es? Unsere Theorie war, dass die Verwendung eines solchen Operators die Zahl in eine ganze Zahl umwandelt und so den Bruchteil entfernt
- Hat es irgendwelche Vorteile gegenüber dem Tun
Math.floor
? Vielleicht ist es etwas schneller? (Wortspiel nicht beabsichtigt) - Hat es irgendwelche Nachteile? Vielleicht funktioniert es in einigen Fällen nicht? Klarheit ist offensichtlich, da wir es herausfinden mussten, und nun, ich schreibe diese Frage.
Vielen Dank.
javascript
floating-point
bit-manipulation
Alex Turpin
quelle
quelle
3000000000.1 | 0
ergibt -1294967296. Daher kann diese Methode nicht für Geldberechnungen angewendet werden (insbesondere in Fällen, in denen Sie mit 100 multiplizieren, um Dezimalzahlen zu vermeiden).0.1 + 0.2 == 0.3
eine JavaScript-Konsole einzugeben . Wenn Ihre Sprache dies unterstützt, sollten Sie einen Dezimaltyp verwenden. Wenn nicht, speichern Sie stattdessen Cent.Antworten:
Alle bitweisen Operationen mit Ausnahme der vorzeichenlosen Rechtsverschiebung
>>>
arbeiten mit vorzeichenbehafteten 32-Bit-Ganzzahlen. Wenn Sie also bitweise Operationen verwenden, wird ein Float in eine Ganzzahl konvertiert.http://jsperf.com/or-vs-floor/2 scheint etwas schneller zu sein
Math.floor(NaN) === NaN
, while(NaN | 0) === 0
quelle
Math.floor(NaN) === NaN
während(NaN | 0) === 0
. Dieser Unterschied kann in einigen Anwendungen wichtig sein.asm.js
(wo ich zuerst davon erfahren habe). Es ist schneller, wenn auch aus keinem anderen Grund, da es keine Funktion für dasMath
Objekt aufruft , eine Funktion, die jederzeit wie in ersetzt werden kannMath.floor = function(...)
.(value | 0) === value
könnte verwendet werden, um zu überprüfen, ob ein Wert tatsächlich eine Ganzzahl und nur eine Ganzzahl ist (wie im verknüpften Elm-Quellcode @ dwayne-crooks). Undfoo = foo | 0
könnte verwendet werden, um einen beliebigen Wert in eine Ganzzahl zu zwingen (wobei 32-Bit-Zahlen abgeschnitten werden und alle Nicht-Zahlen 0 werden).Dies ist eine Kürzung im Gegensatz zu Bodenbelägen. Howards Antwort ist irgendwie richtig; Aber ich würde hinzufügen, dass
Math.floor
dies genau das tut, was es in Bezug auf negative Zahlen tun soll. Mathematisch ist das ein Boden.Im Fall , dass Sie oben beschrieben, war der Programmierer mehr daran interessiert, Abschneiden oder das Dezimalsystem Abhacken vollständig. Die von ihnen verwendete Syntax verdeckt jedoch die Tatsache, dass sie den Float in einen Int konvertieren.
quelle
Math.floor(8589934591.1)
das erwartete Ergebnis erzeugt wird,8589934591.1 | 0
NICHT .In ECMAScript 6, der das Äquivalent
|0
ist Math.trunc , sollte Art , sage ich:quelle
Math.trunc()
mit einer Zahl höher oder gleich 2 ^ 31 arbeiten und| 0
nichtIhr erster Punkt ist richtig. Die Zahl wird in eine Ganzzahl umgewandelt und somit werden alle Dezimalstellen entfernt. Bitte beachten Sie, dass
Math.floor
auf die nächste Ganzzahl in Richtung minus unendlich gerundet wird und daher bei Anwendung auf negative Zahlen ein anderes Ergebnis erzielt wird.quelle
Javascript steht
Number
für 64-Bit-Floating-Zahlen mit doppelter Genauigkeit .Math.floor
arbeitet in diesem Sinne.Bitweise Operationen funktionieren in vorzeichenbehafteten 32-Bit- Ganzzahlen. Ganzzahlen mit 32-Bit-Vorzeichen verwenden das erste Bit als negativen Bezeichner und die anderen 31 Bits sind die Zahl. Aus diesem Grund sind die zulässigen 32-Bit-Nummern mit minimaler und maximaler Signatur -2.147.483.648 bzw. 2147483647 (0x7FFFFFFFF).
Wenn Sie es also tun
| 0
, tun Sie es im Wesentlichen& 0xFFFFFFFF
. Dies bedeutet, dass jede Zahl, die als 0x80000000 (2147483648) oder höher dargestellt wird, als negative Zahl zurückgegeben wird.Beispielsweise:
Ebenfalls. Bitweise Operationen "boden" nicht. Sie kürzen , was das gleiche ist wie zu sagen, sie runden am nächsten
0
. Sobald Sie gehen um zu negativen ZahlenMath.floor
Runde nach unten , während bitweise Start Rundung nach oben .Wie ich bereits sagte,
Math.floor
ist sicherer, weil es mit schwebenden 64-Bit-Zahlen arbeitet. Bitweise ist zwar schneller , aber auf den mit 32 Bit signierten Bereich beschränkt.Zusammenfassen:
0 to 2147483647
.-2147483647 to 0
.-2147483648
und größer als völlig anders2147483647
.Wenn Sie die Leistung wirklich optimieren und beides verwenden möchten:
Das Hinzufügen
Math.trunc
funktioniert wie bitweise Operationen. So können Sie Folgendes tun:quelle
Die Spezifikationen besagen, dass es in eine Ganzzahl konvertiert wird:
Leistung: Dies wurde bereits bei jsperf getestet .
Hinweis: Toter Link zur Spezifikation entfernt
quelle