Math.floor VS Math.trunc JavaScript

Lesezeit: 5 Minuten

Benutzeravatar von Flame_Phoenix
Flamme_Phönix

Hintergrund

Ich mache eine Funktion, die a empfängt positive Zahl und rundet dann die Zahl auf die nächste ganze Zahl darunter.

Ich habe verwendet Math.flooraber vor kurzem entdeckte ich Math.trunc.

Ich bin mir bewusst, dass beide bei einer positiven Zahl den gleichen Wert zurückgeben und dass sie auf völlig unterschiedliche Weise funktionieren. Ich interessiere mich für die Erforschung dieses Verhaltens.

Fragen

  1. Welche ist schneller?
  2. Welche sollte ich verwenden?

  • Es wird in allen Browsern unterstützt, das ist mir bewusst. Ich frage mich nur, wie viel Einfluss die Verwendung jedes einzelnen hat. Deshalb habe ich diese Fragen erstellt, aber die Community scheint es nicht zu mögen :S

    – Flamme_Phönix

    1. August 2016 um 15:39 Uhr

  • Wenn Sie mit „es“ meinen Math.truncdu liegst falsch. Math.trunc ist sehr neu und wird nicht in jedem Browser unterstützt.

    – Sebastian Simon

    1. August 2016 um 15:40 Uhr

  • @Xufox: Du hast recht. Ich habe IE aus meiner Bewertung verworfen, aber andererseits ist es mir egal, und ich glaube auch nicht, dass es jemand in seinem perfekten Sinne tun würde: p

    – Flamme_Phönix

    1. August 2016 um 15:42 Uhr

  • Vielen Dank. Ich fühle mich gleich! Vielen Dank für die Freundlichkeit!

    – Flamme_Phönix

    1. August 2016 um 16:54 Uhr

  • Ich habe einen schnellen Leistungstest durchgeführt, und der Unterschied pro Vorgang auf meinem Computer beträgt etwa 0,00001 Millisekunden. Mit anderen Worten, der Unterschied ist fast immer praktisch bedeutungslos.

    – JJJ

    2. August 2016 um 7:57 Uhr

Benutzeravatar von Qwerty
Qwerty

Tatsächlich gibt es viel mehr alternative Möglichkeiten, die Dezimalstellen aus einer Zahl zu entfernen. Aber es ist ein Kompromiss zwischen Lesbarkeit und Geschwindigkeit.

Die Wahl des richtigen hängt davon ab, was Sie brauchen. Wenn Sie nur müssen Dezimalstellen entfernenVerwenden Sie immer trunc() oder bitweise Operatoren.
Das floor(), ceil() und round() unterscheiden sich konzeptionell stark von trunc().

Mathe-Bibliothek

Diese kennen Sie bereits. Verwenden Sie sie immer in einem standardmäßigen, nicht kritischen Code.

var v = 3.14; [Math.trunc(v), Math.round(v), Math.floor(v), Math.ceil(v)]
// prints results

für verschiedene Eingabewerte erhalten Sie diese Ergebnisse

 v        t   r   f   c
 3.87 : [ 3,  4,  3,  4]
 3.14 : [ 3,  3,  3,  4]
-3.14 : [-3, -3, -4, -3]
-3.87 : [-3, -4, -4, -3]

Math.trunc() schneidet weg (kürzt) die Nachkommastellen.
Math.round() Runden gegenüber am nächsten Ganzzahl.
Math.floor() Runden am nächsten niedriger Ganzzahl. 3.5 -> 3 -3.5 -> -4
Math.ceil() Runden am nächsten höher Ganzzahl. 3.5 -> 4 -3.5 -> -3


Aber das macht mehr Spaß 🙂

Binäre Operationen u bitweise Operatoren

Wenn man sie sich im Code ansieht, ist es vielleicht nicht auf den ersten Blick ersichtlich, was sie tun, also nicht Verwenden Sie sie in normalem Code. In einigen Fällen können sie jedoch nützlich sein. Zum Beispiel die Berechnung von Koordinaten in a <canvas/>. Sie sind viel schneller, haben aber Einschränkungen.

Konzeptionell funktionieren sie so:

  • Die Operanden sind in 32-Bit-Ganzzahlen mit Vorzeichen konvertiert und verlieren somit alle Dezimalbrüche.

AUFMERKSAMKEIT:

Zahlen mit mehr als 32 Bits erhalten ihre höchstwertigen (ganz links stehenden) Bits verworfen und das Bit ganz links wird das neue Vorzeichenbit.

[
  0b011100110111110100000000000000110000000000001, //  15872588537857
~~0b011100110111110100000000000000110000000000001, // -1610588159
             ~~0b10100000000000000110000000000001, // -1610588159
]

Bitweise logische Operatoren

  • Jedes Bit im ersten Operanden wird mit dem entsprechenden Bit im zweiten Operanden gepaart. (Erstes Bit zum ersten Bit, zweites Bit zum zweiten Bit usw.)
  • Der Operator wird auf jedes Bitpaar angewendet und das Ergebnis bitweise konstruiert.

Bitweise Verschiebungsoperatoren

  • Diese Operatoren nehmen a value verschoben werden und a number von Bitpositionen zu verschieben value durch.

abschneiden

Beim Abschneiden verwenden wir jedoch immer a 0null, a false als zweiter Operand, der in diesen Fällen nichts mit dem ursprünglichen Wert macht, außer der Umwandlung in eine ganze Zahl:

~ NICHT ~~v

| ODER v | 0

<< Linksverschiebung v << 0

>> Rechtsverschiebung signiert v >> 0

>>> Zero-Fill-Rechtsverschiebung v >>> 0

var v = 3.78;
[ ~~v ,  v | 0 ,  v << 0 ,  v >> 0 ,  v >>> 0 ]
// prints these results

 3.78 : [ 3,  3,  3,  3, 3]
 3.14 : [ 3,  3,  3,  3, 3]
-3.74 : [-3, -3, -3, -3, 4294967293]
-3.14 : [-3, -3, -3, -3, 4294967293]

Leistung

https://jsperf.com/number-truncating-methods/1

Geben Sie hier die Bildbeschreibung ein

  • Sehr schlechte Idee. Große Zahlen durchlaufen nicht bitweise Operatoren, wie Sie denken. Versuchen Sie (Date.now()+0.5)>>>0. Gibt dir nicht die richtige Antwort. Verwenden Sie keine bitweisen Operatoren zum Festlegen eines Werts, es sei denn, Sie erledigen leistungskritische Arbeiten und wissen, dass die Zahlen immer klein sein werden. Grafikarbeit wäre ein Beispiel.

    – Jason Mitchell

    28. Oktober 2019 um 17:53 Uhr


  • @JasonMitchell Das wurde eigentlich in der Antwort geschrieben, aber ich habe es hervorgehoben, falls mehr Leute das vermissen, wie Sie es getan haben. Danke aber für den Hinweis.

    – QWERTZ

    28. Oktober 2019 um 18:21 Uhr

Wenn das Argument eine positive Zahl ist, entspricht Math.trunc() Math.floor(), andernfalls entspricht Math.trunc() Math.ceil().

für die Leistungsüberprüfung dieses und das schnellste ist Math.trunc

var t0 = performance.now();
var result = Math.floor(3.5);
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);
var t0 = performance.now();
var result = Math.trunc(3.5);
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);

Das Ergebnis ist Generierung dauerte 0,0300 Millisekunden: 3 Generierung dauerte 0,0200 Millisekunden: 3

Wenn die Argumente also nur positive Zahlen sind, können Sie die schnellste verwenden.

  • @StevenHansen Sieht für mich nach einer lustigen Herausforderung aus! Wie viel würdest du als angemessenen Wert bezeichnen? 1 Million? vielleicht 2?

    – Flamme_Phönix

    1. August 2016 um 16:56 Uhr


  • Das Benchmarking hier erschwert nur die Antwort, die selbst vollkommen einfach ist.

    – Steven Vachon

    27. Februar 2019 um 13:11 Uhr

  • Auf jeden Fall sollte die ausgewählte Antwort auf diese Frage sein!

    – Roman Karagodin

    21. Oktober 2021 um 8:08 Uhr

Benutzeravatar von Arvind Kumar Avinash
Arvind Kumar Avinash

Die vorhandenen Antworten haben die Leistung gut erklärt. Ich konnte jedoch den funktionalen Unterschied zwischen nicht verstehen Math.trunc und Math.floor entweder aus der Frage oder den Antworten, und daher habe ich meine Erkenntnisse in diese Antwort aufgenommen.

Math.trunc rundet eine Zahl auf eine ganze Zahl ab 0 während Math.floor rundet eine Zahl auf eine ganze Zahl ab -Infinity. Wie der folgende Zahlenstrahl zeigt, ist die Richtung für eine positive Zahl gleich, während die Richtung für eine negative Zahl entgegengesetzt ist.

trunc: towards 0    
floor: towards -Infinity


                   -3      -2     -1      0      1      2      3
-Infinity ... ------+----|--+------+------+------+------+--|----+------ .... Infinity
                         b                                 a    

Demo:

var a = 2.3, b = -2.3;
console.log("\t\t\t" + a + "\t\t" + b + "\r\n" + "Math.trunc: " + Math.trunc(a) + "\t\t" + Math.trunc(b) + "\r\n" + "Math.floor: " + Math.floor(a) + "\t\t" + Math.floor(b));

Ausgabe:

            2.3     -2.3
Math.trunc: 2       -2
Math.floor: 2       -3

1404850cookie-checkMath.floor VS Math.trunc JavaScript

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy