Wie überprüfe ich, ob eine Variable in JavaScript eine Ganzzahl ist?

405

Wie überprüfe ich, ob eine Variable in JavaScript eine Ganzzahl ist, und gebe eine Warnung aus, wenn dies nicht der Fall ist? Ich habe es versucht, aber es funktioniert nicht:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>
JBa
quelle
2
Eine Möglichkeit hier ist zu verwenden parseInt.
Paul
2
jsben.ch/#/htLVw - ein Benchmark für die gängigen Methoden
EscapeNetscape
Alle Antworten hier sind wirklich veraltet. Heute empfehle ich, mich an Number.isIntegerden am wenigsten hackigen Weg zu halten.
Benjamin Gruenbaum
@Benjamim was ist, wenn die Zahl eine Zeichenfolge ist, die in eine Ganzzahl konvertiert werden kann? und in HTML ist alles eine Zeichenfolge. Also ist Number.isInteger ("69") falsch
joedotnot

Antworten:

344

Verwenden Sie den Operator === ( strikte Gleichheit ) wie folgt :

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")
Pranag
quelle
95
Dies zählt NaN als ganze Zahl. wirkt auch schlechter gegen meine Methode. jsperf.com/numbers-and-integers
Blake Regalia
2
Wenn Sie Ihr Beispiel durch den obigen Code führen, wird a als Ganzzahl und die andere als Ganzzahl ausgegeben, was der Fall ist. Im Fall von NaN unterscheidet sich auch der Typ von NaN vom Typ des Rückgabewerts von pareInt () .....
Pranag
1
Könntest du etwas näher darauf eingehen? Das "Beispiel" zeigt nur, dass die Verwendung von parseInt zu einer schlechteren Leistung führt als die Verwendung des Schlüsselworttyps und des Moduloperators. aber ich verstehe, was du jetzt meinst (NaN! = NaN)
Blake Regalia
4
@connorbode in Javascript haben alle Zahlen den gleichen Typ (es gibt kein Float oder Double). 2.0 === 2Da die unnötige Dezimalzahl nur eine andere Darstellung derselben Zahl parseInt(2.0) === 2.0ist, entspricht dies parseInt(2) === 2der Wahrheit
Michael Theriot
1
@BlakeRegalia: Obwohl seine Methode schnell ist, übergibt sie nicht alle möglichen Werte aus dieser Antwort: stackoverflow.com/a/14794066/843732
c00000fd
506

Das hängt davon ab, ob Sie auch Zeichenfolgen als potenzielle Ganzzahlen umwandeln möchten.

Das wird es tun:

function isInt(value) {
  return !isNaN(value) && 
         parseInt(Number(value)) == value && 
         !isNaN(parseInt(value, 10));
}

Mit bitweisen Operationen

Einfach analysieren und überprüfen

function isInt(value) {
  var x = parseFloat(value);
  return !isNaN(value) && (x | 0) === x;
}

Kurzschließen und Speichern einer Analyseoperation:

function isInt(value) {
  if (isNaN(value)) {
    return false;
  }
  var x = parseFloat(value);
  return (x | 0) === x;
}

Oder vielleicht beides auf einmal:

function isInt(value) {
  return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value))
}

Tests:

isInt(42)        // true
isInt("42")      // true
isInt(4e2)       // true
isInt("4e2")     // true
isInt(" 1 ")     // true
isInt("")        // false
isInt("  ")      // false
isInt(42.1)      // false
isInt("1a")      // false
isInt("4e2a")    // false
isInt(null)      // false
isInt(undefined) // false
isInt(NaN)       // false

Hier ist die Geige: http://jsfiddle.net/opfyrqwp/28/

Performance

Tests haben ergeben, dass die Kurzschlusslösung die beste Leistung aufweist (ops / s).

// Short-circuiting, and saving a parse operation
function isInt(value) {
  var x;
  if (isNaN(value)) {
    return false;
  }
  x = parseFloat(value);
  return (x | 0) === x;
}

Hier ist ein Benchmark: http://jsben.ch/#/htLVw

Wenn Sie sich für eine kürzere, stumpfe Form des Kurzschlusses interessieren:

function isInt(value) {
  var x;
  return isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
}

Natürlich würde ich vorschlagen, dass der Minifier sich darum kümmert.

krisk
quelle
4
@krisk - Upvoted für mehrere Lösungen. Führen Sie auch einen Schnelltest mit den 4 von Ihnen bereitgestellten Varianten durch: jsperf.com/tfm-is-integer - und stellen Sie fest, dass die Kurzschlusslösung die beste Leistung aufweist.
tfmontague
1
Es kehrt falsch auf 2099999999999999 zurück: - (
jkucharovic
1
@jkucharovic der bitweise ODER-Operator ist der Schuldige. Wenn Sie die nicht bitweise Version verwenden, wird true zurückgegeben.
krisk
1
Dies macht '2.' bewerten zu wahr
Cyberwombat
1
@cyberwombat gut, das ist eine Dezimalzahl 2.0 :-)
Kuba Beránek
120

Angenommen, Sie wissen nichts über die betreffende Variable, sollten Sie diesen Ansatz wählen:

if(typeof data === 'number') {
    var remainder = (data % 1);
    if(remainder === 0) {
        // yes, it is an integer
    }
    else if(isNaN(remainder)) {
        // no, data is either: NaN, Infinity, or -Infinity
    }
    else {
        // no, it is a float (still a number though)
    }
}
else {
    // no way, it is not even a number
}

Einfach gesagt:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}
Blake Regalia
quelle
8
Was meinst du? Dies sucht nach Datentypen in Javascript, "1.0"ist eine Zeichenfolge und daher keine Zahl. Andernfalls 1ist der Wert einer Variablen, wenn Sie ihn so einstellen var my_var=1.0;, was durch diese Funktion korrekt als Ganzzahl identifiziert wird.
Blake Regalia
4
Bald Number.isInteger()wird es funktionieren ... bis dahin ist dies ein guter Weg, dies zu tun
Claudiu
Number.isInteger funktioniert bei mir nicht. Ich muss etwas falsch machen. Blakes Lösung% 1 funktioniert perfekt.
mcmacerson
104

Number.isInteger() scheint der richtige Weg zu sein.

MDN hat auch die folgende Polyfüllung für Browser bereitgestellt, die nicht Number.isInteger()alle IE-Versionen unterstützen.

Link zur MDN-Seite

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};
Walter Roman
quelle
2
MDN hat den Test auf 9007199254740992 entfernt
Bernhard Döbler
2
Dies ist die einfachste und "richtige" Antwort. Ich meine, JavaScript hat bereits die Methode, um auf Ganzzahl zu prüfen. Sie müssen kein neues schreiben. isNaN () testet auf Numerizität, nicht auf Ganzzahl.
Globewalldesk
66

Sie können überprüfen, ob die Nummer einen Rest enthält:

var data = 22;

if(data % 1 === 0){
   // yes it's an integer.
}

Wohlgemerkt, wenn Ihre Eingabe auch Text sein könnte und Sie zuerst überprüfen möchten, ob dies nicht der Fall ist, können Sie zuerst den Typ überprüfen:

var data = 22;

if(typeof data === 'number'){
     // yes it is numeric

    if(data % 1 === 0){
       // yes it's an integer.
    }
}
Nee
quelle
3
@Erwinus: 0 % 1 === 0In der Konsole ausführen . Es wird trueals 0 % 1Rückgabe zurückgegeben 0.
Nein,
Haben Sie es in IE versucht
;-)
1
@Erwinus: 0 % 1kehrt 0im IE9-, IE8- und IE7-Kompatibilitätsmodus zurück.
Nein,
Versuchen Sie es in einem echten alten IE. Außerdem ist es immer eine gute Art der Programmierung, auf Null zu prüfen und sich nicht auf den Browser zu verlassen, was zu tun ist.
Codebeat
62
@Erwinus: Ich denke, Sie haben Ihre Fakten durcheinander gebracht. Ein Fehler beim Teilen durch Null wird verursacht, wenn Sie durch Null teilen, nicht wenn Sie Null durch eine Zahl teilen. Mit der Version von IE überhaupt nichts zu tun.
Nein,
22

Sie können einen einfachen regulären Ausdruck verwenden:

function isInt(value) {
    var er = /^-?[0-9]+$/;
    return er.test(value);
}
Marcio Mazzucato
quelle
15

Zunächst einmal ist NaN eine "Zahl" (ja, ich weiß, es ist komisch, rollen Sie einfach damit) und keine "Funktion".

Sie müssen sowohl prüfen, ob der Typ der Variablen eine Zahl ist, als auch auf Ganzzahlen prüfen, ob ich den Modul verwenden würde.

alert(typeof data === 'number' && data%1 == 0);
Phil
quelle
2
sollte sein: alert (Datentyp == 'Nummer' && (Daten == 0 || Daten% 1 == 0)); Division durch Null zu vermeiden.
Codebeat
19
@Erwinus 0% 1 ist immer noch Division durch 1.
Phil
@Phil, (0 == 0 || 0 % 1 == 0)wird zu bewerten true.
Tomekwi
Oh, übrigens 0 % 1 == 0auch zu bewerten true! %ist keine Teilung!
Tomékwi
13

Seien Sie vorsichtig bei der Verwendung

num% 1

Eine leere Zeichenfolge ('') oder ein Boolescher Wert (true oder false) werden als Ganzzahl zurückgegeben. Vielleicht möchten Sie das nicht tun

false % 1 // true
'' % 1 //true

Number.isInteger (Daten)

Number.isInteger(22); //true
Number.isInteger(22.2); //false
Number.isInteger('22'); //false

eingebaute Funktion im Browser. Unterstützt ältere Browser nicht

Alternativen:

Math.round(num)=== num

Math.round () schlägt jedoch auch für leere Zeichenfolgen und Boolesche Werte fehl

Jhankar Mahbub
quelle
8

So überprüfen Sie, ob eine Ganzzahl wie ein Poster gewünscht wird:

if (+data===parseInt(data)) {return true} else {return false}

Beachten Sie + vor den Daten (konvertiert die Zeichenfolge in eine Zahl) und === für genau.

Hier einige Beispiele:

data=10
+data===parseInt(data)
true

data="10"
+data===parseInt(data)
true

data="10.2"
+data===parseInt(data)
false
user603749
quelle
6
Dies scheint die klügste Lösung für meinen Fall zu sein (wo es mir nichts ausmacht, wenn es sich um eine Ganzzahl in einer Zeichenfolge handelt). Aber warum nicht einfach gehen return (+data===parseInt(data))?
Schweizer Herr
6
if(Number.isInteger(Number(data))){
    //-----
}
Gast
quelle
1
Gleicher Kommentar wie unten: Wird von IE und Safari nicht unterstützt .
Kreuz
@crisscross Wird jetzt von allem unterstützt, außer vom Internet Explorer. Dies ist nur dann von Bedeutung, wenn Sie ältere Betriebssysteme unterstützen.
Ohnmachtssignal
6

Die einfachste und sauberste Lösung vor ECMAScript-6 (die auch robust genug ist, um false zurückzugeben, selbst wenn ein nicht numerischer Wert wie eine Zeichenfolge oder null an die Funktion übergeben wird) lautet wie folgt:

function isInteger(x) { return (x^0) === x; } 

Die folgende Lösung würde ebenfalls funktionieren, wenn auch nicht so elegant wie die oben genannte:

function isInteger(x) { return Math.round(x) === x; }

Beachten Sie, dass Math.ceil () oder Math.floor () in der obigen Implementierung gleich gut (anstelle von Math.round ()) verwendet werden können.

Oder alternativ:

function isInteger(x) { return (typeof x === 'number') && (x % 1 === 0); }

Eine ziemlich häufige falsche Lösung ist die folgende:

function isInteger(x) { return parseInt(x, 10) === x; }

Während dieser parseInt-basierte Ansatz für viele Werte von x gut funktioniert, funktioniert x nicht mehr richtig, sobald er ziemlich groß wird. Das Problem ist, dass parseInt () seinen ersten Parameter vor dem Parsen von Ziffern in einen String zwingt. Sobald die Zahl ausreichend groß wird, wird ihre Zeichenfolgendarstellung daher in Exponentialform dargestellt (z. B. 1e + 21). Dementsprechend versucht parseInt () dann, 1e + 21 zu analysieren, beendet jedoch die Analyse, wenn es das e-Zeichen erreicht, und gibt daher den Wert 1 zurück. Beachten Sie:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

> parseInt(1000000000000000000000, 10) === 1000000000000000000000
false
Arsen Aleksanyan
quelle
6

Warum hat niemand erwähnt Number.isInteger()?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger

Funktioniert perfekt für mich und löst das Problem mit dem NaNAnfang einer Nummer.

Nächte
quelle
1
Beachten Sie, dass dies ES6 ist, sodass ältere Browser (wie IE <= 11) dies nicht unterstützen. Die obigen Dokumente enthalten eine Polyfüllung.
Bischof
Jemand hat es Number.isInteger()3,5 Jahre vor Ihnen erwähnt: stackoverflow.com/a/27424770/5208540
Alex Stragies
Wenn wir einen Wert von einer Eingabe abfangen wollen, überprüfen Sie, ob Number.isInteger immer false zurückgibt, da der Eingabewert vom Datentyp string ist
Shinigamae
6

In ES6 2 werden neue Methoden für Number Object hinzugefügt.

Darin gibt die Number.isInteger () -Methode true zurück, wenn das Argument eine Ganzzahl ist.

Anwendungsbeispiel:

Number.isInteger(10);        // returns true
Number.isInteger(10.5);      // returns false
Arun Joshla
quelle
4

Der Standard ECMA-262 6.0 (ES6) enthält die Funktion Number.isInteger .

Um Unterstützung für alte Browser hinzuzufügen, empfehle ich dringend die Verwendung einer starken und von der Community unterstützten Lösung von:

https://github.com/paulmillr/es6-shim

Das ist reine ES6 JS Polyfills-Bibliothek .

Beachten Sie, dass für diese Bibliothek es5-shim erforderlich ist. Folgen Sie einfach README.md.

Gavenkoa
quelle
4

Sie könnten versuchen, Number.isInteger(Number(value))ob valuees sich um eine Ganzzahl in Zeichenfolgenform handelt, z. B. var value = "23"und Sie möchten, dass dies ausgewertet wird true. Vermeiden Sie es, es zu versuchen, Number.isInteger(parseInt(value))da dies nicht immer den richtigen Wert zurückgibt. Wenn z. B. var value = "23abc"und Sie die parseIntImplementierung verwenden, wird immer noch true zurückgegeben.

Aber wenn Sie streng ganzzahlige Werte wollen, Number.isInteger(value)sollten Sie wahrscheinlich den Trick machen.

gbozee
quelle
1
Beachten Sie, dass dies vom IE nicht unterstützt wird. Wie hier in der Dokumentation angegeben, wurde mein Scrip aus diesem Grund angehalten, insbesondere wenn die
Variable,
4
var x = 1.5;
if(!isNaN(x)){
 console.log('Number');
 if(x % 1 == 0){
   console.log('Integer');
 }
}else {
 console.log('not a number');
}
Hemant
quelle
3
Nach 29 Antworten würde man ein bisschen mehr Erklärungen erwarten, um Ihre Antwort
hervorzuheben
3

Überprüfen Sie, ob die Variable der gleichen Variablen entspricht, die auf eine Ganzzahl gerundet ist, wie folgt:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}
Elliot Bonneville
quelle
Sie können das Problem dieser Funktion bei der Rückkehr truefür sehr einfach beheben NaN, indem Sie einfach !=zu !==den ifBlöcken wechseln und diese invertieren . Dies funktioniert, weil dies NaNder einzige Wert in JavaScript ist, der sich selbst nicht entspricht. Zum Beispiel sollte der neue Codeif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99
3

Außerdem Number.isInteger(). Vielleicht Number.isSafeInteger()ist eine weitere Option hier durch die ES6-angegeben ist .

So füllen Sie Number.isSafeInteger(..)Browser vor ES6 mehrfach aus:

Number.isSafeInteger = Number.isSafeInteger || function(num) {
    return typeof num === "number" && 
           isFinite(num) && 
           Math.floor(num) === num &&
           Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
};
zangw
quelle
3

Number.isInteger() ist der beste Weg, wenn Ihr Browser dies unterstützt. Wenn nicht, gibt es meiner Meinung nach so viele Möglichkeiten:

function isInt1(value){
  return (value^0) === value
}

oder:

function isInt2(value){
  return (typeof value === 'number') && (value % 1 === 0); 
}

oder:

function isInt3(value){
  return parseInt(value, 10) === value; 
}

oder:

function isInt4(value){
  return Math.round(value) === value; 
}

Jetzt können wir die Ergebnisse testen:

var value = 1
isInt1(value)   // return true
isInt2(value)   // return true
isInt3(value)   // return true
isInt4(value)   // return true

var value = 1.1
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = 1000000000000000000
isInt1(value)   // return false
isInt2(value)   // return true
isInt3(value)   // return false
isInt4(value)   // return true

var value = undefined
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

var value = '1' //number as string
isInt1(value)   // return false
isInt2(value)   // return false
isInt3(value)   // return false
isInt4(value)   // return false

Alle diese Methoden funktionieren also, aber wenn die Anzahl sehr groß ist, funktionieren parseInt und ^ operator nicht gut.

Charles Chu
quelle
3

Versuchen Sie einfach Folgendes:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}
Jan WebDev
quelle
Number.isInteger () wird nicht in allen Versionen von IE-Browsern unterstützt.
SKR
2

Sie können diese Funktion verwenden:

function isInteger(value) {
    return (value == parseInt(value));
}

Es wird true zurückgegeben, auch wenn der Wert eine Zeichenfolge ist, die einen ganzzahligen Wert enthält.
Die Ergebnisse werden also sein:

alert(isInteger(1)); // true
alert(isInteger(1.2)); // false
alert(isInteger("1")); // true
alert(isInteger("1.2")); // false
alert(isInteger("abc")); // false
Ferhrosa
quelle
2

Mein Ansatz:

a >= 1e+21Test kann nur für einen Wert bestehen, der eine Zahl und sein muss eine sehr große sein muss. Dies wird sicher alle Fälle abdecken, im Gegensatz zu anderen Lösungen, die in dieser Diskussion bereitgestellt wurden.

a === (a|0)Wenn das Argument der angegebenen Funktion genau ist (===) mit dem bitweise transformierten Wert übereinstimmt, bedeutet dies, dass das Argument eine Ganzzahl ist.

a|0wird wieder 0für jeden Wert von , adass keine Zahl ist , und wenn aja eine Zahl ist, wird es etwas nach dem Komma abstreifen, so 1.0001wird sich1

function isInteger(a){
    return a >= 1e+21 ? true : a === (a|0)
}

/// tests ///////////////////////////
[
  1,                        // true
  1000000000000000000000,   // true
  4e2,                      // true
  Infinity,                 // true
  1.0,                      // true
  1.0000000000001,          // false
  0.1,                      // false
  "0",                      // false
  "1",                      // false
  "1.1",                    // false
  NaN,                      // false
  [],                       // false
  {},                       // false
  true,                     // false
  false,                    // false
  null,                     // false
  undefined                 // false
].forEach( a => console.log(typeof a, a, isInteger(a)) )

vsync
quelle
1
Gute Idee! Ich mag es auch, dass Sie Ihre Tests gezeigt haben, aber dies berücksichtigt leider keinen String-Wert von "0".
Jammer
Hey @vsync, nicht absichtlich. Ich habe ursprünglich positiv gestimmt, mich aber aufgrund meines vorherigen Kommentars entschlossen, es zurückzusetzen. Ich muss versehentlich doppelt darauf geklickt haben oder so.
Jammer
1

Sie können Regexp dafür verwenden:

function isInteger(n) {
    return (typeof n == 'number' && /^-?\d+$/.test(n+''));
}
Macloving
quelle
1

Verwenden Sie den |Operator:

(5.3 | 0) === 5.3 // => false
(5.0 | 0) === 5.0 // => true

Eine Testfunktion könnte also folgendermaßen aussehen:

var isInteger = function (value) {
  if (typeof value !== 'number') {
    return false;
  }

  if ((value | 0) !== value) {
    return false;
  }

  return true;
};
Golo Roden
quelle
1

Dies löst ein weiteres Szenario ( 121. ), einen Punkt am Ende

function isInt(value) {
        var ind = value.indexOf(".");
        if (ind > -1) { return false; }

        if (isNaN(value)) {
            return false;
        }

        var x = parseFloat(value);
        return (x | 0) === x;

    }
Muhammed Rafiq
quelle
1

Für positive ganzzahlige Werte ohne Trennzeichen:

return ( data !== '' && data === data.replace(/\D/, '') );

Testet 1. wenn nicht leer und 2. wenn der Wert gleich dem Ergebnis eines Ersetzens eines nichtstelligen Zeichens in seinem Wert ist.

DanielL
quelle
1

Ok wurde minus, weil mein Beispiel nicht beschrieben wurde, also mehr Beispiele :):

Ich benutze reguläre Ausdrücke und Testmethoden:

var isInteger = /^[0-9]\d*$/;

isInteger.test(123); //true
isInteger.test('123'); // true
isInteger.test('sdf'); //false
isInteger.test('123sdf'); //false

// If u want to avoid string value:
typeof testVal !== 'string' && isInteger.test(testValue);
Vasyl Gutnyk
quelle
Ich habe wahrscheinlich ein Minus erhalten, weil der Test keine Funktion ist.
Imlokesh
@imlokesh was meinst du "ist keine Funktion"? oO Ich schrieb, ich benutze "Testmethode".
Vasyl Gutnyk
@imlokesh kein Problem, ich frage dich nur, weil ich es in der Produktion verwendet habe :) und ich dachte, du
hast
1

Sie können es auch so versuchen

var data = 22;
if (Number.isInteger(data)) {
    console.log("integer");
 }else{
     console.log("not an integer");
 }

oder

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}
Adeojo Emmanuel IMM
quelle
Dies führt zu einem falschen Ergebnis für data=22.5;. Auch beide Zweige haben console.log("not an integer"):: S
Colin Breame
0

Ich musste überprüfen, ob eine Variable (Zeichenfolge oder Zahl) eine Ganzzahl ist, und ich habe diese Bedingung verwendet:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a);
}

http://jsfiddle.net/e267369d/1/

Einige der anderen Antworten haben eine ähnliche Lösung (verlassen Sie sich auf parseFloatkombiniert mitisNaN ), aber meine sollte direkter und selbsterklärender sein.


Bearbeiten: Ich habe herausgefunden, dass meine Methode für Zeichenfolgen mit Komma (wie "1,2") fehlschlägt, und ich habe auch festgestellt, dass in meinem speziellen Fall die Funktion fehlschlagen soll, wenn eine Zeichenfolge keine gültige Ganzzahl ist (sollte bei einem Float fehlschlagen) sogar 1,0). Also hier ist meine Funktion Mk II:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a) && (typeof a != 'string' || (a.indexOf('.') == -1 && a.indexOf(',') == -1));
}

http://jsfiddle.net/e267369d/3/

Natürlich können Sie die Punktbedingung jederzeit entfernen, falls Sie die Funktion tatsächlich benötigen, um Ganzzahl-Floats (1.0-Zeug) zu akzeptieren a.indexOf('.') == -1.

jahu
quelle