Come verificare se una variabile è un numero intero in JavaScript?


405

Come posso verificare se una variabile è un numero intero in JavaScript e inviare un avviso se non lo è? Ho provato questo, ma non funziona:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>

2
Una possibilità qui è di usare parseInt.
Paul

2
jsben.ch/#/htLVw - un punto di riferimento per i modi comuni per farlo
EscapeNetscape

Tutte le risposte qui sono davvero obsolete. Oggi consiglio di attenersi a Number.isIntegerquale sia il modo meno confuso.
Benjamin Gruenbaum,

@Benjamim cosa succede se il numero è una stringa che può essere convertita in un numero intero? e in HTML tutto è una stringa .. quindi Number.isInteger ("69") è falso
joedotnot

Risposte:


344

Utilizzare l'operatore === ( uguaglianza rigorosa ) come di seguito,

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")

95
questo conta NaN come un numero intero. funziona anche peggio contro il mio metodo. jsperf.com/numbers-and-integers
Blake Regalia

2
se esegui il tuo esempio attraverso il codice sopra, avvisa a come intero e l'altro come non intero che è il caso ... nel caso di NaN anche il tipo di NaN è diverso dal tipo del valore restituito da pareInt () .....
pranag

1
potresti elaborare un po '? l '"esempio" sta solo dimostrando che l'utilizzo di parseInt produce prestazioni peggiori rispetto all'utilizzo della parola chiave typeof e dell'operatore modulo. ma capisco cosa intendi adesso (NaN! = NaN)
Blake Regalia,

4
@connorbode in javascript tutti i numeri hanno lo stesso tipo (non c'è float o double), quindi 2.0 === 2poiché il decimale non necessario è solo una rappresentazione diversa dello stesso numero, quindi parseInt(2.0) === 2.0è equivalente a quello parseInt(2) === 2che è vero
Michael Theriot

1
@BlakeRegalia: Pur essendo veloce il suo metodo non passa tutti i valori possibili da questa risposta: stackoverflow.com/a/14794066/843732
C00000FD

506

Dipende, vuoi anche lanciare stringhe come numeri interi potenziali?

Questo farà:

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

Con operazioni Bitwise

Analisi e controllo semplici

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

Cortocircuito e salvataggio di un'operazione di analisi:

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

O forse entrambi in un colpo solo:

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

test:

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

Ecco il violino: http://jsfiddle.net/opfyrqwp/28/

Prestazione

I test rivelano che la soluzione di corto circuito ha le migliori prestazioni (ops / sec).

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

Ecco un benchmark: http://jsben.ch/#/htLVw

Se desideri una forma più corta e ottusa di corto circuito:

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

Ovviamente, suggerirei di occuparsene.


4
@krisk - Eseguito l'upgrade per più soluzioni. Ha inoltre eseguito un test rapido sulle 4 varianti fornite: jsperf.com/tfm-is-integer - e ha stabilito che la soluzione di cortocircuito ha le migliori prestazioni.
tfmontague,

1
Sta tornando falso il 209999999999999999: - (
jkucharovic il

1
@jkucharovic l'operatore bitwise OR è il colpevole. L'uso della versione non bit a bit restituirà true.
Krisk,

1
Questo rende '2.' valuta vero
cyberwombat,

1
@cyberwombat bene che è un numero decimale 2.0 :-)
Kuba Beránek

120

Supponendo che non si sappia nulla della variabile in questione, è necessario adottare questo approccio:

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
}

Per dirla semplicemente:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}

8
Cosa intendi? Controlla i tipi di dati in javascript, "1.0"è una stringa e non è quindi un numero. Altrimenti 1sarà il valore di una variabile se la imposti in questo modo var my_var=1.0;, che viene correttamente identificato da questa funzione come intero.
Blake Regalia,

4
Presto Number.isInteger()funzionerà ... fino ad allora, questo è un buon modo per farlo
Claudiu,

Number.isInteger non funziona per me. Devo fare qualcosa di sbagliato. La soluzione di Blake% 1 funziona perfettamente.
mcmacerson,

104

Number.isInteger() sembra essere la strada da percorrere.

MDN ha inoltre fornito il seguente polyfill per i browser che non supportano Number.isInteger(), principalmente tutte le versioni di IE.

Link alla pagina MDN

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};


2
Questa è la risposta più semplice e "corretta". Voglio dire, JavaScript ha già il metodo per verificare l'integrità. Non c'è bisogno di scriverne uno nuovo. isNaN () verifica la numericità, non l'intera.
globewalldesk,

66

Puoi verificare se il numero ha un resto:

var data = 22;

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

Intendiamoci, se il tuo input potrebbe anche essere un testo e vuoi verificare prima che non lo sia, allora puoi controllare prima il tipo:

var data = 22;

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

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

3
@Erwinus: esegui 0 % 1 === 0nella console. Ritorna truecome 0 % 1ritorna 0.
No,

Hai provato in IE ;-)
Codebeat

1
@Erwinus: 0 % 1ritorna 0in modalità di compatibilità IE9, IE8 e IE7.
No,

Provalo in un vero vecchio IE. inoltre è sempre un buon modo di programmare verificare lo zero e non fare affidamento sul browser cosa fare.
Codebeat

62
@ Erwinus: penso che tu abbia confuso i tuoi fatti. Una divisione per errore zero è causata quando si divide per zero e non quando si divide zero per un numero. Niente a che vedere con la versione di IE.
No,

22

Puoi usare una semplice espressione regolare:

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

15

Prima di tutto, NaN è un "numero" (sì, lo so che è strano, basta scorrere con esso), e non una "funzione".

È necessario verificare sia se il tipo della variabile è un numero, sia per verificare il numero intero, utilizzare il modulo.

alert(typeof data === 'number' && data%1 == 0);

2
dovrebbe essere: avviso (tipo di dati == 'numero' && (dati == 0 || dati% 1 == 0)); per evitare la divisione per zero.
Codebeat

19
@Erwinus 0% 1 è ancora in divisione per 1.
Phil

@Phil, (0 == 0 || 0 % 1 == 0)valuterà a true.
tomekwi,

Oh, a proposito, 0 % 1 == 0valuta anche true! %non è divisione!
tomekwi,

13

Fai attenzione durante l'utilizzo

num% 1

stringa vuota ('') o booleana (vero o falso) tornerà come intero. Potresti non volerlo fare

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

Number.isInteger (dati)

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

funzione integrata nel browser. Dosnt supporta i browser più vecchi

alternative:

Math.round(num)=== num

Tuttavia, Math.round () fallirà anche per stringa vuota e booleana


8

Per verificare se intero come vuole il poster:

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

avviso + davanti ai dati (converte la stringa in numero) e === per l'esatto.

Ecco alcuni esempi:

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

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

data="10.2"
+data===parseInt(data)
false

6
Questa sembra la soluzione più intelligente per il mio caso (dove non mi dispiace se è un numero intero in una stringa). Tuttavia: perché non semplicemente andare return (+data===parseInt(data))?
Mister svizzero,


6

La soluzione pre-ECMAScript-6 più semplice e pulita (che è anche sufficientemente robusta per restituire false anche se un valore non numerico come una stringa o null viene passato alla funzione) sarebbe la seguente:

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

La seguente soluzione funzionerebbe anche, sebbene non elegante come quella sopra:

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

Nota che Math.ceil () o Math.floor () potrebbero essere usati ugualmente bene (anziché Math.round ()) nell'implementazione sopra.

O in alternativa:

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

Una soluzione errata abbastanza comune è la seguente:

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

Mentre questo approccio basato su parseInt funzionerà bene per molti valori di x, una volta che x diventa abbastanza grande, non funzionerà correttamente. Il problema è che parseInt () costringe il suo primo parametro a una stringa prima di analizzare le cifre. Pertanto, una volta che il numero diventa sufficientemente grande, la sua rappresentazione in forma di stringa verrà presentata in forma esponenziale (ad es. 1e + 21). Di conseguenza, parseInt () tenterà quindi di analizzare 1e + 21, ma smetterà di analizzare quando raggiunge il carattere e e quindi restituirà un valore di 1. Osservare:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

> parseInt(1000000000000000000000, 10) === 1000000000000000000000
false

6

Perché nessuno ha menzionato Number.isInteger()?

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

Funziona perfettamente per me e risolve il problema con l' NaNinizio di un numero.


1
Si noti che questo è ES6, quindi i browser meno recenti (come IE <= 11) non lo supportano. I documenti sopra forniscono un polyfill.
vescovo

Qualcuno ha fatto menzione Number.isInteger(), 3,5 anni prima: stackoverflow.com/a/27424770/5208540
Alex Stragies

se prendiamo un valore da un input, quindi controlla, Number.isInteger restituirà sempre false poiché il valore di input è del tipo di dati stringa
Shinigamae

6

In ES6 vengono aggiunti 2 nuovi metodi per l'oggetto numero.

In esso il metodo Number.isInteger () restituisce true se l'argomento è un numero intero.

Esempio di utilizzo:

Number.isInteger(10);        // returns true
Number.isInteger(10.5);      // returns false

4

Lo standard ECMA-262 6.0 (ES6) include Number.isInteger funzione .

Per aggiungere il supporto per il vecchio browser, consiglio vivamente di utilizzare una soluzione forte e supportata dalla comunità da:

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

che è pura libreria di polifilloli ES6 JS .

Nota che questa libreria richiede es5-shim, basta seguire README.md.


4

Puoi provare Number.isInteger(Number(value))se valuepotrebbe essere un numero intero in forma di stringa, ad esempio var value = "23"e vuoi che questo valuti true. Evita di provare Number.isInteger(parseInt(value))perché questo non restituirà sempre il valore corretto. ad es. se var value = "23abc"e utilizzi l' parseIntimplementazione, tornerebbe comunque vero.

Ma se vuoi valori rigorosamente interi, probabilmente Number.isInteger(value)dovresti fare il trucco.


1
Si noti che questo non è supportato da IE; come indicato qui nel documento, il mio script è stato interrotto a causa di ciò, specialmente se il var che stai controllando non è definito
mikewasmike,

4
var x = 1.5;
if(!isNaN(x)){
 console.log('Number');
 if(x % 1 == 0){
   console.log('Integer');
 }
}else {
 console.log('not a number');
}

3
Dopo 29 risposte, ci si aspetterebbe un po 'più di spiegazioni per far risaltare la tua risposta ...
brasofilo,

3

Controlla se la variabile è uguale alla stessa variabile arrotondata a un numero intero, in questo modo:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}

Si può facilmente risolvere numero di questa funzione con il ritorno trueper NaN, semplicemente cambiando !=per !==e invertendo i ifblocchi. Questo funziona perché NaNè l'unico valore in JavaScript che non è uguale a se stesso. Ad esempio, il nuovo codice dovrebbe essereif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99

3

Inoltre, Number.isInteger(). Forse Number.isSafeInteger()è un'altra opzione qui usando ES6 specificato.

Per eseguire il polyfill Number.isSafeInteger(..)nei browser pre-ES6:

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

3

Number.isInteger() è il modo migliore se il tuo browser lo supporta, in caso contrario, penso che ci siano così tanti modi per andare:

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

o:

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

o:

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

o:

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

ora possiamo testare i risultati:

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

Quindi, tutti questi metodi funzionano, ma quando il numero è molto grande, l'operatore parseInt e ^ non funzionerebbe bene.


3

Prova questo:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}

Number.isInteger () non è supportato in tutte le versioni dei browser IE.
SKR

2

È possibile utilizzare questa funzione:

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

Restituirà vero anche se il valore è una stringa contenente un valore intero.
Quindi, i risultati saranno:

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

2

Il mio approccio:

a >= 1e+21Il test può passare solo per un valore che deve essere un numero e un valore molto grande. Questo coprirà sicuramente tutti i casi, a differenza di altre soluzioni fornite in questa discussione.

a === (a|0)Se l'argomento della funzione data è esattamente (===) uguale al valore trasformato bit a bit, significa che l'argomento è un numero intero.

a|0ritornerà 0per qualsiasi valore ache non sia un numero , e se aè davvero un numero, toglierà qualsiasi cosa dopo il punto decimale, quindi 1.0001diventerà1

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


1
Buona idea! Mi piace anche che tu abbia mostrato i tuoi test ma sfortunatamente questo non considera un valore String di "0".
Jammer,

Ehi @vsync, non intenzionalmente. Inizialmente ho votato, ma ho deciso di ripristinarlo a causa del mio commento precedente. Devo averlo fatto doppio clic accidentalmente o qualcosa del genere.
Jammer,

1

Puoi usare regexp per questo:

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


1

Usa l' |operatore:

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

Quindi, una funzione di test potrebbe apparire così:

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

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

  return true;
};

1

Questo risolverà un altro scenario ( 121. ), un punto alla fine

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;

    }

1

Per valori interi positivi senza separatori:

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

Test 1. se non vuoto e 2. se il valore è uguale al risultato di una sostituzione di un carattere non cifra nel suo valore.


1

Ok ho meno, perché non ho descritto il mio esempio, quindi altri esempi :):

Uso l'espressione regolare e il metodo di prova:

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

Probabilmente meno perché il test non è una funzione.
imlokesh,

@imlokesh cosa intendi con "non è una funzione"? oO Ho scritto che utilizzo il "metodo di prova".
Vasyl Gutnyk,

@imlokesh nessun problema, ti chiedo solo perché l'ho usato in produzione :) e pensavo che
avessi

1

puoi anche provarlo in questo modo

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

o

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}

Questo produrrà il risultato sbagliato per data=22.5;. Inoltre entrambi i rami hanno console.log("not an integer"):: S
Colin Breame il

0

Ho dovuto verificare se una variabile (stringa o numero) è un numero intero e ho usato questa condizione:

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

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

Alcune delle altre risposte hanno una soluzione simile (si basano su parseFloatcombinate con isNaN), ma la mia dovrebbe essere più semplice e autoesplicativa.


Modifica: ho scoperto che il mio metodo non riesce per le stringhe contenenti virgola (come "1,2") e mi sono anche reso conto che nel mio caso particolare voglio che la funzione fallisca se una stringa non è un intero valido (dovrebbe fallire su qualsiasi float , anche 1.0). Quindi ecco la mia funzione 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/

Ovviamente nel caso in cui sia effettivamente necessaria la funzione per accettare float interi (roba 1.0), è sempre possibile rimuovere la condizione punto a.indexOf('.') == -1.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.