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>

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

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.


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
}

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

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.
    }
}

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

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

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


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

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

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

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.


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

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.


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.


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

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!");
}

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

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.


3

Coba saja ini:

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

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

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


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+''));
}


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

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;

    }

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.


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

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

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.