Bagaimana cara memeriksa apakah suatu variabel bilangan bulat dalam JavaScript?

405

Bagaimana cara saya memeriksa apakah suatu variabel bilangan bulat dalam JavaScript, dan memberikan peringatan jika tidak? Saya mencoba ini, tetapi tidak berhasil:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>
JBa
sumber
2
Satu kemungkinan di sini adalah menggunakan parseInt.
Paul
2
jsben.ch/#/htLVw - patokan untuk cara umum melakukannya
EscapeNetscape
Semua jawaban di sini benar-benar ketinggalan zaman. Hari ini, saya sarankan tetap pada Number.isIntegeryang merupakan cara paling tidak hacky.
Benjamin Gruenbaum
@ Benjamim bagaimana jika nomornya adalah string yang dapat dikonversi ke integer? dan dalam HTML semuanya adalah string .. jadi Number.isInteger ("69") salah
joedotnot

Jawaban:

344

Gunakan operator === ( kesetaraan ketat ) seperti di bawah ini,

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")
pranag
sumber
95
ini menghitung NaN sebagai bilangan bulat. juga berkinerja lebih buruk terhadap metode saya. jsperf.com/numbers-and-integers
Blake Regalia
2
jika Anda menjalankan contoh Anda melalui kode di atas itu mengingatkan sebagai bilangan bulat dan yang lainnya bukan bilangan bulat yang terjadi ... dalam kasus NaN juga jenis NaN berbeda dari jenis nilai pengembalian pareInt () .....
pranag
1
bisakah kamu menguraikan sedikit? "contoh" hanya menunjukkan bahwa menggunakan parseInt menghasilkan kinerja yang lebih buruk daripada menggunakan jenis kata kunci dan operator modulus. tapi saya mengerti maksud Anda sekarang (NaN! = NaN)
Blake Regalia
4
@connorbode dalam javascript semua angka memiliki tipe yang sama (tidak ada float atau double), jadi 2.0 === 2karena desimal yang tidak perlu hanyalah representasi berbeda dari angka yang sama, dengan demikian parseInt(2.0) === 2.0sama dengan parseInt(2) === 2yang benar
Michael Theriot
1
@BlakeRegalia: Meskipun cepat, metodenya tidak lulus semua nilai yang mungkin dari jawaban ini: stackoverflow.com/a/14794066/843732
c00000fd
506

Itu tergantung, apakah Anda juga ingin menggunakan string sebagai bilangan bulat potensial juga?

Ini akan melakukan:

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

Dengan operasi Bitwise

Penguraian sederhana dan periksa

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

Hubungan arus pendek, dan menyimpan operasi parse:

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

Atau mungkin keduanya dalam satu kesempatan:

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

Tes:

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

Ini biola: http://jsfiddle.net/opfyrqwp/28/

Performa

Pengujian menunjukkan bahwa solusi hubungan arus pendek memiliki kinerja terbaik (ops / dtk).

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

Berikut ini adalah patokan: http://jsben.ch/#/htLVw

Jika Anda menginginkan hubungan arus pendek yang tumpul, tumpul:

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

Tentu saja, saya sarankan membiarkan minifier merawatnya.

keripik
sumber
4
@krisk - Dipilih untuk beberapa solusi. Juga melakukan tes cepat pada 4 varian yang Anda berikan: jsperf.com/tfm-is-integer - dan menentukan bahwa solusi korsleting memiliki kinerja terbaik.
tfmontague
1
Ini kembali salah pada 2099999999999999: - (
jkucharovic
1
@jkucharovic operator bitwise ATAU adalah pelakunya. Menggunakan versi non-bitwise akan mengembalikan true.
krisk
1
Ini membuat '2.' evaluasikan ke true
cyberwombat
1
@cyberwombat baik itu adalah angka desimal 2.0 :-)
Kuba Beránek
120

Dengan asumsi Anda tidak tahu apa-apa tentang variabel yang dimaksud, Anda harus mengambil pendekatan ini:

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
}

Untuk membuatnya lebih sederhana:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}
Blake Regalia
sumber
8
Apa maksudmu? Ini memeriksa tipe data dalam javascript, "1.0"adalah string, dan karenanya bukan angka. Kalau tidak, 1akan menjadi nilai variabel jika Anda menetapkannya var my_var=1.0;, yang diidentifikasi dengan benar oleh fungsi ini sebagai integer.
Blake Regalia
4
Segera, Number.isInteger()akan bekerja ... sampai saat itu, ini adalah cara yang baik untuk melakukannya
Claudiu
Number.isInteger tidak bekerja untuk saya. Saya pasti melakukan sesuatu yang salah. Solusi Blake% 1 bekerja dengan sempurna.
mcmacerson
104

Number.isInteger() tampaknya menjadi cara untuk pergi.

MDN juga menyediakan polyfill berikut untuk browser yang tidak mendukung Number.isInteger(), terutama semua versi IE.

Tautan ke halaman MDN

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};
Walter Roman
sumber
2
MDN menjalani tes pada 9007199254740992 dihapus
Bernhard Döbler
2
Ini adalah jawaban yang paling mudah dan "benar". Maksud saya, JavaScript sudah memiliki metode untuk memeriksa integerhood. Tidak perlu menulis yang baru. isNaN () menguji numerisitas, bukan integerhood.
globewalldesk
66

Anda dapat memeriksa apakah nomor tersebut memiliki sisa:

var data = 22;

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

Pikiran Anda, jika input Anda juga bisa berupa teks dan Anda ingin memeriksa dulu bukan, maka Anda dapat memeriksa jenisnya terlebih dahulu:

var data = 22;

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

    if(data % 1 === 0){
       // yes it's an integer.
    }
}
Nggak
sumber
3
@ Erwinus: Jalankan 0 % 1 === 0di konsol. Ia kembali truesebagai 0 % 1pengembalian 0.
Tidak
Sudahkah Anda mencobanya di IE ;-)
Codebeat
1
@ Erwinus: 0 % 1mengembalikan 0dalam mode kompatibilitas IE9, IE8 dan IE7.
Tidak
Cobalah di IE lama nyata. selain itu selalu merupakan cara pemrograman yang baik untuk memeriksa nol dan tidak bergantung pada browser apa yang harus dilakukan.
Codebeat
62
@ Erwinus: Saya pikir Anda terlibat dalam fakta. Pembagian dengan kesalahan nol disebabkan ketika Anda membaginya dengan nol bukan ketika Anda membaginya dengan angka. Tidak ada hubungannya dengan versi IE sama sekali.
Tidak
22

Anda dapat menggunakan ekspresi reguler sederhana:

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

Pertama, NaN adalah "angka" (ya saya tahu itu aneh, cukup gunakan saja), dan bukan "fungsi".

Anda perlu memeriksa keduanya jika jenis variabel adalah angka, dan untuk memeriksa bilangan bulat saya akan menggunakan modulus.

alert(typeof data === 'number' && data%1 == 0);
Phil
sumber
2
harus: waspada (typeof data == 'number' && (data == 0 || data% 1 == 0)); untuk menghindari pembagian dengan nol.
Codebeat
19
@Erwinus 0% 1 masih dibagi dengan 1.
Phil
@ Phil, (0 == 0 || 0 % 1 == 0)akan dievaluasi untuk true.
tomekwi
Oh, omong-omong 0 % 1 == 0juga mengevaluasi untuk true! %bukan pembagian!
tomekwi
13

Hati-hati saat menggunakan

num% 1

string kosong ('') atau boolean (benar atau salah) akan kembali sebagai bilangan bulat. Anda mungkin tidak ingin melakukan itu

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

Number.isInteger (data)

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

membangun fungsi di browser. Dosnt mendukung browser lama

Alternatif:

Math.round(num)=== num

Namun, Math.round () juga akan gagal untuk string kosong dan boolean

Jhankar Mahbub
sumber
8

Untuk memeriksa apakah bilangan bulat seperti poster ingin:

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

perhatikan + di depan data (mengkonversi string ke angka), dan === untuk tepat.

Berikut ini contohnya:

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

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

data="10.2"
+data===parseInt(data)
false
pengguna603749
sumber
6
Ini sepertinya solusi paling cerdas untuk kasus saya (di mana saya tidak keberatan jika bilangan bulat dalam sebuah string). Namun: mengapa tidak pergi saja return (+data===parseInt(data))?
Swiss Mister
6
if(Number.isInteger(Number(data))){
    //-----
}
tamu
sumber
1
Komentar yang sama seperti di bawah ini: Tidak didukung oleh IE dan Safari .
merambah
@ crisscross Sekarang didukung oleh segalanya kecuali IE, yang hanya menjadi masalah jika Anda mendukung sistem operasi lawas.
faintsignal
6

Solusi pre-ECMAScript-6 yang paling sederhana dan paling bersih (yang juga cukup kuat untuk mengembalikan false meskipun nilai non-numerik seperti string atau null dilewatkan ke fungsi) adalah sebagai berikut:

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

Solusi berikut ini juga akan berfungsi, meskipun tidak seindah yang di atas:

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

Perhatikan bahwa Math.ceil () atau Math.floor () dapat digunakan dengan baik (bukan Math.round ()) dalam implementasi di atas.

Atau sebagai alternatif:

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

Salah satu solusi salah yang cukup umum adalah sebagai berikut:

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

Walaupun pendekatan berbasis parseInt ini akan bekerja dengan baik untuk banyak nilai x, begitu x menjadi cukup besar, ia akan gagal berfungsi dengan baik. Masalahnya adalah parseInt () memaksa parameter pertama ke string sebelum mengurai digit. Oleh karena itu, setelah jumlahnya menjadi cukup besar, representasi stringnya akan disajikan dalam bentuk eksponensial (misalnya, 1e + 21). Karenanya, parseInt () kemudian akan mencoba mem-parse 1e + 21, tetapi akan berhenti parsing ketika mencapai karakter e dan karenanya akan mengembalikan nilai 1. Perhatikan:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

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

Kenapa belum ada yang bilang Number.isInteger()?

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

Berfungsi sempurna untuk saya dan menyelesaikan masalah dengan angka NaNawal.

malam
sumber
1
Perhatikan bahwa ini adalah ES6, jadi peramban yang lebih lama (seperti IE <= 11) tidak mendukungnya. Dokumen di atas menyediakan polyfill.
Uskup
Seseorang memang menyebutkan Number.isInteger(), 3,5 tahun sebelum Anda: stackoverflow.com/a/27424770/5208540
Alex Stragies
jika kita akan menangkap nilai dari input lalu memeriksa, Number.isInteger akan selalu mengembalikan false karena nilai inputnya adalah string datatype
Shinigamae
6

Dalam ES6 2 metode baru ditambahkan untuk Number Object.

Di dalamnya metode Number.isInteger () mengembalikan true jika argumennya adalah integer.

Contoh penggunaan:

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

ECMA-262 6.0 (ES6) standar termasuk fungsi Number.isInteger .

Untuk menambahkan dukungan untuk browser lama, saya sangat merekomendasikan menggunakan solusi yang kuat dan didukung komunitas dari:

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

yang merupakan perpustakaan ES6 JS polyfills murni .

Perhatikan bahwa lib ini memerlukan es5-shim, cukup ikuti README.md.

gavenkoa
sumber
4

Anda dapat mencoba Number.isInteger(Number(value))jika valuemungkin bilangan bulat dalam bentuk string misalnya var value = "23"dan Anda ingin ini dievaluasi true. Hindari mencoba Number.isInteger(parseInt(value))karena ini tidak selalu mengembalikan nilai yang benar. mis. jika var value = "23abc"dan Anda menggunakan parseIntimplementasi, itu masih akan mengembalikan true.

Tetapi jika Anda ingin nilai integer ketat maka mungkin Number.isInteger(value)harus melakukan trik.

gbozee
sumber
1
Perhatikan bahwa ini tidak didukung oleh IE; seperti yang dinyatakan di sini dalam dokumen, skrip saya terhenti karena ini terutama jika var yang Anda periksa tidak terdefinisi
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');
}
Hemant
sumber
3
Setelah 29 jawaban, orang akan mengharapkan sedikit lebih banyak penjelasan untuk membuat jawaban Anda menonjol ...
brasofilo
3

Periksa apakah variabel sama dengan variabel yang sama dibulatkan ke integer, seperti ini:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}
Elliot Bonneville
sumber
Anda dapat dengan mudah memperbaiki masalah ini fungsi dengan kembali trueuntuk NaN, hanya dengan mengubah !=ke !==dan membalik ifblok. Ini berfungsi karena NaNmerupakan satu-satunya nilai dalam JavaScript yang tidak sama dengan dirinya. Misalnya, kode baru harusif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99
3

Selain itu Number.isInteger(),. Mungkin Number.isSafeInteger()ada opsi lain di sini dengan menggunakan ES6 yang ditentukan.

Untuk Number.isSafeInteger(..)mengisi polyfill di browser pra-ES6:

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

Number.isInteger() adalah cara terbaik jika browser Anda mendukungnya, jika tidak, saya pikir ada banyak cara untuk melakukannya:

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

atau:

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

atau:

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

atau:

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

sekarang kita dapat menguji hasilnya:

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

Jadi, semua metode ini berfungsi, tetapi ketika jumlahnya sangat besar, operator parseInt dan ^ tidak akan berfungsi dengan baik.

Charles Chu
sumber
3

Coba saja ini:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}
Jan WebDev
sumber
Number.isInteger () tidak didukung di semua versi browser IE.
SKR
2

Anda dapat menggunakan fungsi ini:

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

Ini akan mengembalikan true bahkan jika nilainya adalah string yang berisi nilai integer.
Jadi, hasilnya adalah:

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

Pendekatan saya:

a >= 1e+21Tes hanya dapat lulus untuk nilai yang harus berupa angka dan nilai yang sangat besar. Ini akan mencakup semua kasus pasti, tidak seperti solusi lain yang telah disediakan dalam diskusi ini.

a === (a|0)Jika argumen fungsi yang diberikan tepat (===) sama dengan nilai bitwise-transformed, itu berarti bahwa argumen tersebut adalah bilangan bulat.

a|0akan kembali 0untuk nilai apa pun ayang bukan angka , dan jika amemang angka, itu akan menghapus apa pun setelah titik desimal, sehingga 1.0001akan menjadi1

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
sumber
1
Ide bagus! Saya juga suka Anda menunjukkan tes Anda tetapi sayangnya ini tidak mempertimbangkan nilai String "0".
Jammer
Hey @vsync, Tidak sengaja. Saya memang awalnya memilih tetapi memutuskan untuk mengembalikannya kembali karena komentar saya sebelumnya. Saya pasti tidak sengaja mengklik dua kali atau sesuatu.
Jammer
1

Anda dapat menggunakan regexp untuk ini:

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

Gunakan |operator:

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

Jadi, fungsi tes mungkin terlihat seperti ini:

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

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

  return true;
};
Golo Roden
sumber
1

Ini akan menyelesaikan satu skenario lagi ( 121. ), sebuah titik di akhir

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
sumber
1

Untuk nilai integer positif tanpa pemisah:

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

Tes 1. jika tidak kosong dan 2. jika nilainya sama dengan hasil penggantian karakter non-digit pada nilainya.

DanielL
sumber
1

Ok jadi minus, karena tidak menggambarkan contoh saya, jadi lebih banyak contoh :):

Saya menggunakan ekspresi reguler dan metode pengujian:

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
sumber
Mendapat minus mungkin karena tes bukan fungsi.
imlokesh
@imlokesh apa maksudmu "bukan fungsi"? oO saya menulis saya menggunakan "metode pengujian".
Vasyl Gutnyk
@imlokesh tidak masalah, saya hanya meminta Anda karena saya menggunakannya dalam produksi :) dan saya pikir Anda menemukan beberapa bug :)
Vasyl Gutnyk
1

Anda juga bisa mencobanya dengan cara ini

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

atau

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}
Adeojo Emmanuel IMM
sumber
Ini akan menghasilkan hasil yang salah untuk data=22.5;. Juga kedua cabang memiliki console.log("not an integer"):: S
Colin Breame
0

Saya harus memeriksa apakah variabel (string atau angka) adalah bilangan bulat dan saya menggunakan kondisi ini:

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

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

Beberapa jawaban lain memiliki solusi yang sama (andalkan parseFloatdigabungkan dengan isNaN), tetapi jawaban saya harus lebih mudah dan jelas.


Sunting: Saya menemukan bahwa metode saya gagal untuk string yang mengandung koma (seperti "1,2") dan saya juga menyadari bahwa dalam kasus khusus saya ingin fungsi gagal jika string bukan bilangan bulat yang valid (harus gagal pada float apa pun , bahkan 1.0). Jadi inilah fungsi saya 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/

Tentu saja jika Anda benar-benar membutuhkan fungsi untuk menerima integer floats (1.0 stuff), Anda selalu dapat menghapus kondisi titik a.indexOf('.') == -1.

jahu
sumber