1549 Stimmen

Wie konvertiere ich in JavaScript eine Fließkommazahl in eine ganze Zahl?

Ich möchte in JavaScript einen Float in eine ganze Zahl umwandeln. Eigentlich würde ich gerne wissen, wie man BEIDE Standardkonvertierungen durchführt: durch Abschneiden und Runden. Und effizient, nicht über die Umwandlung in eine Zeichenfolge und Parsing.

105 Stimmen

Wenn Sie es nicht wussten, sind alle Zahlen in Javascript Floats. Aus der Spezifikation:

8 Stimmen

4.3.20 Nummerntyp: Der Typ Number ist eine Menge von Werten, die Zahlen darstellen. In ECMAScript repräsentiert der Wertesatz die doppelpräzisen 64-Bit-Werte im IEEE-754-Format, einschließlich der speziellen "Not-a-Number"-Werte (NaN), positive Unendlichkeit und negative Unendlichkeit.

13 Stimmen

Ja, Javascript hat keine eindeutige "Integer"-Typ, aber es ist immer noch nicht ungewöhnlich, diese Konvertierung zu tun müssen. In meiner Anwendung gaben die Benutzer beispielsweise eine Zahl ein (möglicherweise einschließlich Cents). Ich musste die Cents abschneiden und mit Kommas anzeigen. Schritt 1 war die Konvertierung in int.

2225voto

moonshadow Punkte 81155
var intvalue = Math.floor( floatvalue );
var intvalue = Math.ceil( floatvalue ); 
var intvalue = Math.round( floatvalue );

// `Math.trunc` was added in ECMAScript 6
var intvalue = Math.trunc( floatvalue );

Referenz auf ein mathematisches Objekt


Beispiele

Positiv

// value=x        //  x=5          5<x<5.5      5.5<=x<6  

Math.floor(value) //  5            5            5
Math.ceil(value)  //  5            6            6
Math.round(value) //  5            5            6
Math.trunc(value) //  5            5            5
parseInt(value)   //  5            5            5
~~value           //  5            5            5
value | 0         //  5            5            5
value >> 0        //  5            5            5
value >>> 0       //  5            5            5
value - value % 1 //  5            5            5

Negativ

// value=x        // x=-5         -5>x>=-5.5   -5.5>x>-6

Math.floor(value) // -5           -6           -6
Math.ceil(value)  // -5           -5           -5
Math.round(value) // -5           -5           -6
Math.trunc(value) // -5           -5           -5
parseInt(value)   // -5           -5           -5
value | 0         // -5           -5           -5
~~value           // -5           -5           -5
value >> 0        // -5           -5           -5
value >>> 0       // 4294967291   4294967291   4294967291
value - value % 1 // -5           -5           -5

Positiv - Größere Zahlen

// x = Number.MAX_SAFE_INTEGER/10 // =900719925474099.1

// value=x            x=900719925474099    x=900719925474099.4  x=900719925474099.5

Math.floor(value) //  900719925474099      900719925474099      900719925474099
Math.ceil(value)  //  900719925474099      900719925474100      900719925474100
Math.round(value) //  900719925474099      900719925474099      900719925474100
Math.trunc(value) //  900719925474099      900719925474099      900719925474099
parseInt(value)   //  900719925474099      900719925474099      900719925474099
value | 0         //  858993459            858993459            858993459
~~value           //  858993459            858993459            858993459
value >> 0        //  858993459            858993459            858993459
value >>> 0       //  858993459            858993459            858993459
value - value % 1 //  900719925474099      900719925474099      900719925474099

Negativ - Größere Zahlen

// x = Number.MAX_SAFE_INTEGER/10 * -1 // -900719925474099.1

// value = x      // x=-900719925474099   x=-900719925474099.5 x=-900719925474099.6

Math.floor(value) // -900719925474099     -900719925474100     -900719925474100
Math.ceil(value)  // -900719925474099     -900719925474099     -900719925474099
Math.round(value) // -900719925474099     -900719925474099     -900719925474100
Math.trunc(value) // -900719925474099     -900719925474099     -900719925474099
parseInt(value)   // -900719925474099     -900719925474099     -900719925474099
value | 0         // -858993459           -858993459           -858993459
~~value           // -858993459           -858993459           -858993459
value >> 0        // -858993459           -858993459           -858993459
value >>> 0       //  3435973837           3435973837           3435973837
value - value % 1 // -900719925474099     -900719925474099     -900719925474099

90 Stimmen

Wie bereits in einer anderen Antwort erwähnt, kann eine negativ-sichere Trunkierung mit var intValue = ~~floatValue; . Wenn die Notation für Ihren Geschmack zu obskur ist, verstecken Sie sie einfach in einer Funktion: function toInt(value) { return ~~value; } . (Dies konvertiert auch Zeichenketten in Ganzzahlen, wenn Sie dies wünschen).

6 Stimmen

Ich würde eine höhere Bewertung abgeben, wenn diese Antwort Beispieleingaben/-ausgaben enthielte.

11 Stimmen

Bezüglich des Kommentars ~~ begrenzt den Wert auf 32 Bit vorzeichenbehaftete Ganzzahlen, während Math.floor/ceil/round bis zu 53 Bit verarbeiten kann (Number.MAX_SAFE_INTEGER 9007199254740991). Dies wird in der Antwort unten erwähnt, aber es lohnt sich, es hier für diejenigen zu wiederholen, die diese Kommentare lesen.

343voto

Robert Koritnik Punkte 100480

Bitweiser OR-Operator

Ein bitweiser oder Operator kann verwendet werden, um Fließkommazahlen abzuschneiden, und er funktioniert sowohl für positive als auch für negative Werte:

function float2int (value) {
    return value | 0;
}

Ergebnisse

float2int(3.1) == 3
float2int(-3.1) == -3
float2int(3.9) == 3
float2int(-3.9) == -3

Leistungsvergleich?

Ich habe eine JSPerf-Test die die Leistung zwischen vergleicht:

  • Math.floor(val)
  • val | 0 bitweise OR
  • ~~val bitweise NICHT
  • parseInt(val)

die nur mit positiven Zahlen funktioniert. In diesem Fall sind Sie sicher, dass Sie bitweise Operationen ebenso verwenden können wie Math.floor Funktion.

Aber wenn Sie Ihren Code brauchen, um sowohl mit positiven als auch mit negativen Aspekten arbeiten dann ist eine bitweise Operation am schnellsten (OR ist die bevorzugte). Dieser andere JSPerf-Test vergleicht dasselbe, wobei es ziemlich offensichtlich ist, dass aufgrund der zusätzlichen Zeichenprüfung Mathe ist jetzt am langsamsten der vier.

Hinweis

Wie in den Kommentaren angegeben, arbeiten die BITWISE-Operatoren mit vorzeichenbehafteten 32-Bit-Ganzzahlen, daher werden große Zahlen umgewandelt, Beispiel:

1234567890  | 0 => 1234567890
12345678901 | 0 => -539222987

0 Stimmen

@FabioPoloni: ja super einfach und es scheint, dass bitweise Operatoren am schnellsten sind. Vor allem der OR-Operator ist immer der schnellste, oft gefolgt von NOT und mathematischen Operationen, obwohl mathematische Operationen am langsamsten sind, wenn man auch negative Zahlen unterstützen muss, da eine zusätzliche Prüfung des Vorzeichens erfolgt.

12 Stimmen

@thefourtheye: Alle bitweisen Operationen, mit Ausnahme der vorzeichenlosen Rechtsverschiebung, funktionieren mit vorzeichenbehafteten 32-Bit-Ganzzahlen. Wenn Sie also bitweise Operationen auf Fließkommawerte anwenden, werden diese in eine Ganzzahl umgewandelt, wobei die Nachkommastellen entfernt werden.

0 Stimmen

Bitweise Not ist leistungsfähig in Bezug auf die Geschwindigkeit.

101voto

Hinweis: Sie können nicht verwenden Math.floor() als Ersatz für truncate, denn Math.floor(-3.1) = -4 und nicht -3 !!

Ein korrekter Ersatz für truncate wäre:

function truncate(value)
{
    if (value < 0) {
        return Math.ceil(value);
    }

    return Math.floor(value);
}

1 Stimmen

Das hängt von dem gewünschten Verhalten für negative Zahlen ab. Bei einigen Verwendungen müssen negative Zahlen auf den negativeren Wert abgebildet werden (-3,5 -> -4) und bei anderen auf die kleinere ganze Zahl (-3,5 -> -3). Ersteres wird normalerweise "Floor" genannt. Das Wort "truncate" wird oft verwendet, um beide Verhaltensweisen zu beschreiben. In meinem Fall wollte ich nur negative Zahlen eingeben. Aber dieser Kommentar ist eine nützliche Warnung für diejenigen, die sich für das Verhalten bei negativen Zahlen interessieren.

29 Stimmen

@mcherm: Dann scheinen sie den Begriff "truncate" nicht richtig zu verstehen. Truncate macht genau das, was der Name sagt: Es schneidet Ziffern ab. Es ist niemals (im allgemeinen Sinne) äquivalent zu floor oder ceil. de.wikipedia.org/wiki/Trunkierung

6 Stimmen

Math.trunc(value) wurde in ECMAScript 6 hinzugefügt

50voto

brad Punkte 70548

Ein Doppel bitweise nicht Operator kann verwendet werden, um Fließkommazahlen abzuschneiden. Die anderen von Ihnen erwähnten Operationen sind verfügbar über Math.floor , Math.ceil y Math.round .

> ~~2.5
2
> ~~(-1.4)
-1

Weitere Einzelheiten mit freundlicher Genehmigung von James Padolsey.

1 Stimmen

Dies ist wahrscheinlich eine schlechte Sache, um für die Produktion Code zu tun (da es obskur ist), aber es war genau das, was ich für Code-Golfing benötigt meine <canvas> Schriftart-Rendering-Engine in JS . Ich danke Ihnen!

11 Stimmen

Dies kann auch mit n | 0 erreicht werden.

20 Stimmen

Beachten Sie, dass beide Methoden (~~n oder n|0) nur für Zahlen bis zu 2^31-1, oder 2147483647, funktionieren. 2147483648 oder höher liefert ein falsches Ergebnis; zum Beispiel liefert 2147483647|0 -2147483648, und 4294967295|0 liefert -1, was mit Sicherheit nicht das ist, was Sie wollen.

43voto

Mike Punkte 8693

Für truncate:

var intvalue = Math.floor(value);

Für die Runde:

var intvalue = Math.round(value);

7 Stimmen

Math.floor schneidet negative Werte nicht ab. Siehe Antwort oben. Ansonsten gute Antwort.

0 Stimmen

Wenn Sie an der Leistung interessiert sind, habe ich hier einen kleinen Testfall eingestellt: jsperf.com/dsafdgdfsaf/2 (var | 0 gewinnt hier).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X