Wie konvertiere ich eine Float-Nummer in JavaScript in eine ganze Zahl?

1110

Ich möchte einen Float in JavaScript in eine ganze Zahl konvertieren. Eigentlich möchte ich wissen, wie BEIDE Standardkonvertierungen durchgeführt werden: durch Abschneiden und Runden. Und effizient, nicht durch Konvertieren in einen String und Parsen.

mcherm
quelle
83
Wenn Sie es nicht wussten, sind alle Zahlen in Javascript Floats. Aus der Spezifikation:
einige
6
4.3.20 Nummerntyp: Der Typ Nummer ist eine Reihe von Werten, die Zahlen darstellen. In ECMAScript repräsentiert der Wertesatz die IEEE 754-Werte im 64-Bit-Format mit doppelter Genauigkeit, einschließlich der speziellen NaN-Werte (Not-a-Number), der positiven Unendlichkeit und der negativen Unendlichkeit.
einige
9
Ja, Javascript hat keinen eindeutigen "Integer" -Typ, aber es ist immer noch nicht ungewöhnlich, dass diese Konvertierung durchgeführt werden muss. In meiner Anwendung haben Benutzer beispielsweise eine Zahl eingegeben (möglicherweise einschließlich Cent). Ich musste die Cent abschneiden und mit Kommas anzeigen. Schritt 1 war die Konvertierung in int.
Mcherm
1
auch nützlich: Geschwindigkeitsvergleich aller Methoden jsperf.com/math-floor-vs-math-round-vs-parseint/33
c ..
1
@karl: Wenn ich Eingaben in ein Feld akzeptiere, kann ich möglicherweise steuern, welche Zeichen ich akzeptiere, aber ich kann alle Arten der Verarbeitung in Javascript durchführen und nicht nur Benutzereingaben akzeptieren. Sogar dann möchte ich es vielleicht für Dinge wie unterstützende Paste.
Mcherm

Antworten:

1609
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 );

Mathe-Objektreferenz


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
Mondschatten
quelle
82
Wie in einer anderen Antwort erwähnt, kann ein negativ-sicheres Abschneiden mit verwendet werden var intValue = ~~floatValue;. Wenn die Notation für Ihren Geschmack zu dunkel ist, verstecken Sie sie einfach in einer Funktion : function toInt(value) { return ~~value; }. (Dies konvertiert auch Zeichenfolgen in Ganzzahlen, wenn Sie dies
Keen
4
Würde positiv stimmen, wenn diese Antwort Beispiel Eingabe / Ausgabe hätte.
J. Random Coder
7
In Bezug auf den Kommentar begrenzt ~~ den Wert auf 32-Bit-Ganzzahlen mit Vorzeichen, 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, dies hier für diejenigen zu wiederholen, die diese Kommentare lesen.
John
2
Lesen Sie an mehreren Stellen von unten: Math.trunc(val);Kommentar, da dies die akzeptierte Antwort ist
Old Badman Gray
Funktioniert nicht mit exakter Genauigkeit für Werte wie2.3 - 2.3 % 1
Lapys
301

Bitweiser ODER-Operator

Ein bitweiser oder Operator kann zum Abschneiden von Gleitkommazahlen verwendet werden und funktioniert sowohl für positive als auch für negative Punkte:

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 einen JSPerf-Test erstellt , der die Leistung vergleicht zwischen:

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

das funktioniert nur mit positiven zahlen. In diesem Fall können Sie sicher bitweise Operationen und Math.floorFunktionen verwenden.

Wenn Sie jedoch Ihren Code benötigen, um sowohl mit positiven als auch mit negativen Ergebnissen zu arbeiten , ist eine bitweise Operation die schnellste (ODER die bevorzugte). Dieser andere JSPerf-Test vergleicht den gleichen, bei dem es ziemlich offensichtlich ist, dass Math aufgrund der zusätzlichen Vorzeichenprüfung jetzt der langsamste der vier ist.

Hinweis

Wie in den Kommentaren angegeben, arbeiten BITWISE-Operatoren mit vorzeichenbehafteten 32-Bit-Ganzzahlen. Daher werden große Zahlen konvertiert. Beispiel:

1234567890  | 0 => 1234567890
12345678901 | 0 => -539222987
Robert Koritnik
quelle
@FabioPoloni: Ja, super einfach und scheint, dass bitweise Operatoren die schnellsten sind. Insbesondere der OR-Operator ist immer der schnellste, der häufig von NOT- und Math-Operationen abgeglichen wird, obwohl Math-Operationen am langsamsten sind, wenn Sie auch negative Zahlen unterstützen müssen, da er eine zusätzliche Überprüfung des Zahlenzeichens hinzufügt.
Robert Koritnik
9
@thefourtheye: Alle bitweisen Operationen außer der vorzeichenlosen Rechtsverschiebung arbeiten mit vorzeichenbehafteten 32-Bit-Ganzzahlen. Wenn Sie daher bitweise Operationen für Gleitkommawerte verwenden, werden diese in eine Ganzzahl umgewandelt, bei der die Ziffern nach dem Dezimalpunkt entfernt werden.
Robert Koritnik
3
Wenn Sie es nur für positive Zahlen benötigen, Math.floor()ist es schneller (zumindest gemäß meiner Ausführung Ihres ersten JSPerf-Tests in Google Chrome, Version 30.0.1599.101), robuster (da es nicht davon abhängt, wie Zahlen in Bits dargestellt werden). was diese bitweise Lösung ändern und möglicherweise brechen kann) und vor allem expliziter.
ma11hew28
8
Beachten Sie, dass die bitweisen Operatoren mit 32-Bit-Zahlen arbeiten. Sie funktionieren nicht für Zahlen, die zu groß sind, um in 32 Bit zu passen.
Kat
2
~~ist besser, weil es ein unärer Operator ist. 4.2|0+4gleich 4aber ~~4.2+4gleich8
Janus Troelsen
94

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

Ein korrekter Ersatz für Abschneiden wäre:

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

    return Math.floor(value);
}
Jackson
quelle
1
Das hängt vom gewünschten Verhalten für negative Zahlen ab. Einige Verwendungen benötigen negative Zahlen, um dem negativeren Wert (-3,5 -> -4) zuzuordnen, und andere erfordern, dass sie der kleineren Ganzzahl (-3,5 -> -3) zugeordnet werden. Ersteres wird normalerweise als "Boden" bezeichnet. Das Wort "abgeschnitten" wird häufig verwendet, um eines der beiden Verhaltensweisen zu beschreiben. In meinem Fall wollte ich nur negative Zahlen eingeben. Dieser Kommentar ist jedoch eine nützliche Warnung für diejenigen, die sich für das Verhalten negativer Zahlen interessieren.
Mcherm
28
@mcherm: Dann scheinen sie den Begriff "abschneiden" nicht richtig zu verstehen. Truncate macht genau das, was der Name schon sagt: Es schneidet Ziffern ab. Es ist niemals (im allgemeinen Sinne) gleichbedeutend mit Boden oder Decke. en.wikipedia.org/wiki/Truncation
Thanatos
5
Math.trunc(value)wurde in ECMAScript 6
4esn0k
2
floorrundet gegen-unendlich, truncaterundet gegen null. ( ceilRunden in Richtung + unendlich).
Peter Cordes
46

Ein doppelter bitweiser Nicht- Operator kann verwendet werden, um Floats abzuschneiden. Die anderen Operationen , die Sie erwähnt sind durch Math.floor, Math.ceilund Math.round.

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

Weitere Details mit freundlicher Genehmigung von James Padolsey.

Brad
quelle
1
Dies ist wahrscheinlich eine schlechte Sache für Produktionscode (da es dunkel ist), aber es war genau das, was ich zum Code-Golfing meiner <canvas>Font-Rendering-Engine in JS brauchte . Vielen Dank!
Kragen Javier Sitaker
10
Dies kann auch mit n | erreicht werden 0.
Jay Douglass
17
Beachten Sie, dass jede Methode (~~ n oder n | 0) nur für Zahlen bis 2 ^ 31-1 oder 2147483647 funktioniert. 2147483648 oder höher gibt ein falsches Ergebnis zurück. Beispielsweise gibt 2147483647 | 0 -2147483648 und 4294967295 | 0 -1 zurück, was mit ziemlicher Sicherheit nicht das ist, was Sie wollen.
Ed Bayiates
40

Zum Abschneiden:

var intvalue = Math.floor(value);

Für Runde:

var intvalue = Math.round(value);
Mike
quelle
6
Math.floor schneidet keine negativen Werte ab. Siehe Antwort oben. Ansonsten schöne Antwort.
Oligofren
Wenn Sie an Leistung interessiert sind, habe ich hier einen kleinen Testfall gestellt: jsperf.com/dsafdgdfsaf/2 (var | 0 gewinnt hier).
Cybolic
25

Sie können die parseInt- Methode ohne Rundung verwenden. Seien Sie vorsichtig mit Benutzereingaben aufgrund der Präfixoptionen 0x (hex) und 0 (oktal).

var intValue = parseInt(floatValue, 10);
Graeme Wicksted
quelle
1
Dies ist tatsächlich hilfreich, wenn Sie nur den ganzzahligen Teil einer Dezimalstelle möchten, ohne auf- oder abzurunden, was .round, .ceil und .floor alles tun.
Judah Gabriel Himango
1
... selbst wenn dies einfach abgeschnitten wird, scheint dies die langsamste Methode zu sein. jsperf.com/float-to-int-conversion-comparison
Robert Koritnik
2
Übergeben Sie immer den 2. Wert an parseInt, um anzugeben, welche Basis Sie erwarten. Also, parseInt (floatValue, 10), um immer Basis 10 zu erhalten.
Tim Tisdall
3
Obwohl dies alt ist, scheint diese Frage eine zu sein, die ziemlich oft gestellt wird, deshalb werde ich dies hier als Warnung einfügen. Wenn der Wert aufgrund seiner Größe mit der Notation "e" dargestellt wird, ergibt sich nur eine Ziffer, nicht das, was erwartet wird. Zum Beispiel parseInt(1000000000000000000000, 10);ergibt sich 1, nicht 1 000 000 000 000 000 000 000. Wie auch immer, die Frage wollte ausdrücklich nicht " in einen String konvertieren und analysieren ", obwohl das relativ gering ist ...;)
Qantas 94 Heavy
4
@ Qantas94Heavy Der Grund für dieses Verhalten ist, parseInt()dass eine Zeichenfolge keine Zahl als erster Parameter erwartet . Wenn Sie diese Ganzzahl übergeben, wird sie in die Zeichenfolge konvertiert 1e21und parseIntanalysiert diese. Daraus 1e21resultiert 1.
Olaf Dietsche
18

Bitverschiebung um 0, was einer Division durch 1 entspricht

// >> or >>>
2.0 >> 0; // 2
2.0 >>> 0; // 2
Prasanth
quelle
4
Kleine Anmerkung: >> 0scheint nur für ganze Zahlen < 2 ^ 31-1 und >>> 0für ganze Zahlen < 2 ^ 32-1 zu funktionieren . Dies gibt 0 für größere Werte zurück
Romuald Brunet
@RomualdBrunet, ja, JavaScript definiert alle bitweisen Operationen eindeutig als Operationen mit 32-Bit-Zahlen. Das steht in den Spezifikationen.
Alexis Wilke
Dies funktioniert, da Javascript bitweise Operationen nur mit 32-Bit-Ganzzahlen (mit Vorzeichen) ausführt, wie in der obigen Antwort angegeben. Daher benötigt jede Bitoperation, die nichts zu tun scheint (wie eine Verschiebung für 0 ODER mit 0 UND mit 1, doppelt NICHT), weiterhin einen Javascript-Interpreter, um den Wert in 32-Bit-Int zu konvertieren.
FrankKrumnow
9

In Ihrem Fall, wenn Sie am Ende eine Zeichenfolge möchten (um Kommas einzufügen), können Sie auch einfach die Number.toFixed()Funktion verwenden, dies führt jedoch eine Rundung durch.

Russell Leggett
quelle
7

Hier gibt es viele Vorschläge. Das bitweise ODER scheint bei weitem das einfachste zu sein. Hier ist eine weitere kurze Lösung, die auch mit negativen Zahlen unter Verwendung des Modulo-Operators funktioniert. Es ist wahrscheinlich einfacher zu verstehen als das bitweise ODER:

intval = floatval - floatval%1;

Diese Methode funktioniert auch mit hohen Zahlen, bei denen weder '| 0' noch '~~' noch '>> 0' korrekt funktionieren:

> n=4294967295;
> n|0
-1
> ~~n
-1
> n>>0
-1
> n-n%1
4294967295
Juliane Holzt
quelle
Wenn Sie sich auf eine andere Antwort beziehen, fügen Sie entweder einen Verweis darauf hinzu oder skizzieren Sie kurz die Idee.
Bertl
5

So abschneiden :

// Math.trunc() is part of the ES6 spec
Math.trunc( 1.5 );  // returns 1
Math.trunc( -1.5 ); // returns -1
// Math.floor( -1.5 ) would return -2, which is probably not what you wanted

Zum Runden :

Math.round( 1.5 );  // 2
Math.round( 1.49 ); // 1
Math.round( -1.6 ); // -2
Math.round( -1.3 ); // -1
Rasierer
quelle
5

Ein weiterer möglicher Weg - verwenden Sie die XOR-Operation:

console.log(12.3 ^ 0); // 12
console.log("12.3" ^ 0); // 12
console.log(1.2 + 1.3 ^ 0); // 2
console.log(1.2 + 1.3 * 2 ^ 0); // 3
console.log(-1.2 ^ 0); // -1
console.log(-1.2 + 1 ^ 0); // 0
console.log(-1.2 - 1.3 ^ 0); // -2

Die Priorität von bitweisen Operationen ist geringer als die Priorität von mathematischen Operationen, es ist nützlich. Versuchen Sie es mit https://jsfiddle.net/au51uj3r/

Dmitry Kharitonov
quelle
2

Wenn Sie sich ein natives MathObjekt in JavaScript ansehen , erhalten Sie eine ganze Reihe von Funktionen, mit denen Sie Zahlen und Werte usw. bearbeiten können.

Grundsätzlich ist das, was Sie tun möchten, in JavaScript recht einfach und nativ ...

Stellen Sie sich vor, Sie haben die folgende Nummer:

const myValue = 56.4534931;

und jetzt, wenn Sie es auf die nächste Zahl abrunden möchten, tun Sie einfach:

const rounded = Math.floor(myValue);

und du bekommst:

56

Wenn Sie es auf die nächste Zahl aufrunden möchten, gehen Sie einfach wie folgt vor:

const roundedUp = Math.ceil(myValue);

und du bekommst:

57

Auch Math.roundnur auf eine höhere oder niedrigere Zahl abrunden, hängt davon ab, welche näher an der Flotzahl liegt.

Sie können auch ~~hinter der Gleitkommazahl verwenden, um einen Gleitkommawert in eine ganze Zahl umzuwandeln.

Sie können es verwenden wie ~~myValue...

Alireza
quelle
Seien Sie vorsichtig mit dem, ~~denn wenn die Zahl größer als der Grenzwert für int 32 ist, ändert sich der Wert in den Grenzwert für int 32.
Machado
1

//Convert a float to integer

Math.floor(5.95)
//5

Math.ceil(5.95)
//6

Math.round(5.4)
//5

Math.round(5.5)
//6

Math.trunc(5.5)
//5

//Quick Ways
console.log(5.95| 0)
console.log(~~5.95) 
console.log(5.95 >> 0)
//5

pk_code
quelle
0

Ich möchte nur darauf hinweisen, dass Sie monetär runden und nicht abschneiden möchten. Es ist viel weniger wahrscheinlich, dass Sie um einen Cent davonkommen, da 4,999452 * 100 gerundet 5 ergibt, eine repräsentativere Antwort.

Vergessen Sie außerdem nicht die Rundung des Bankiers , um der leicht positiven Tendenz entgegenzuwirken, die eine gerade Rundung mit sich bringt - Ihre finanzielle Anwendung erfordert dies möglicherweise.

Gaußsche / Banker-Rundung in JavaScript

Gerard ONeill
quelle
0

Wenn Sie anglejs verwenden, gehen Sie wie folgt vor: In HTML Template Binding

{{val | number:0}}

es wird val in eine ganze Zahl umwandeln

Gehen Sie mit diesem Link durch docs.angularjs.org/api/ng/filter/number

Jameel Grand
quelle