Як перевірити, чи є змінною ціле число в JavaScript?


405

Як перевірити, чи є змінна цілим числом у JavaScript, і подати попередження, якщо це не так? Я спробував це, але це не працює:

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

2
Однією з позитивних можливостей тут є використання parseInt.
Пол

2
jsben.ch/#/htLVw - орієнтир для поширених способів зробити це
EscapeNetscape

Усі відповіді тут справді застаріли. Сьогодні я рекомендую дотримуватися того, Number.isIntegerякий є найменш хакітим способом.
Бенджамін Грюнбаум

@Benjamim, що якщо число - це рядок, який можна перетворити на ціле число? а в HTML все - рядок .. тому Number.isInteger ("69") помилковий
joedotnot

Відповіді:


344

Використовуйте оператор === ( сувора рівність ), як показано нижче,

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

95
це рахує NaN як ціле число. також погіршує мій метод. jsperf.com/numbers-and-integers
Blake Regalia

2
якщо ви запускаєте свій приклад за допомогою наведеного вище коду, він попереджає як ціле число, а інше як не ціле число, що є випадком ... у випадку NaN також тип NaN відрізняється від типу повернутого значення pareInt () .....
pranag

1
Ви могли б трохи допрацювати? "приклад" лише демонструє, що використання parseInt дає гірші показники, ніж використання ключового слова typeof та оператора модуля. але я бачу, про що ти зараз йдеш (NaN! = NaN)
Блейк Регалія

4
@connorbode в javascript усі номери мають один і той же тип (немає поплавця або подвійного), тому 2.0 === 2що непотрібний десятковий знак - це просто інше представлення одного і того ж числа, таким чином parseInt(2.0) === 2.0, еквівалентний parseInt(2) === 2істинному
Michael Theriot

1
@BlakeRegalia: Незважаючи на те, що швидко його метод НЕ проходить всі можливі значення з цієї відповіді: stackoverflow.com/a/14794066/843732
C00000FD

506

Від цього залежить, чи хочете ви також передавати рядки як потенційні цілі числа?

Це зробить:

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

З побітними операціями

Простий розбір і перевірка

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

Коротке замикання та збереження операції розбору:

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

Або, можливо, обидва в одному кадрі:

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

Тести:

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

Ось загадка: http://jsfiddle.net/opfyrqwp/28/

Продуктивність

Тестування показує, що рішення короткого замикання має найкращі показники (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;
}

Ось орієнтир: http://jsben.ch/#/htLVw

Якщо вам подобається коротша, тупа форма короткого замикання:

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

Звичайно, я б запропонував дозволити мініфікатору подбати про це.


4
@krisk - запропоновано декілька рішень. Також провели швидкий тест на 4 запропоновані вами варіанти: jsperf.com/tfm-is-integer - і визначили, що рішення короткого замикання має найкращі показники.
tfmontague

1
Повертається помилково 2099999999999999: - (
jkucharovic

1
@jkucharovic винуватцем оператора чи АБО. Використання небітової версії поверне істину.
krisk

1
Це робить "2." оцінити по правді
cyberwombat

1
@cyberwombat добре, що це десяткове число 2,0 :-)
Kuba Beránek

120

Припускаючи, що ви нічого не знаєте про змінну, про яку йдеться, слід скористатися таким підходом:

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
}

Простіше кажучи:

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

8
Що ви маєте на увазі? Це перевіряє типи даних у JavaScript, "1.0"є рядком і тому не є числом. Інакше 1буде значення змінної, якщо ви встановите її таким чином var my_var=1.0;, що правильно ідентифікується цією функцією як ціле число.
Блейк Регалія

4
Незабаром Number.isInteger()буде працювати ... до тих пір, це хороший спосіб зробити це
Клавдіу,

Number.isInteger не працює для мене. Я мушу щось робити не так. Розчин Блейка% 1 прекрасно працює.
mcmacerson

104

Number.isInteger() здається, шлях.

MDN також надав наступну полісистему для браузерів, які не підтримують Number.isInteger(), в основному, всі версії IE.

Посилання на сторінку MDN

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

2
MDN має тест на 9007199254740992 видалений
Bernhard Döbler

2
Це найпростіша і «правильна» відповідь. Я маю на увазі, у JavaScript вже є метод перевірки на цілість. Не потрібно писати нове. isNaN () тести на числовість, а не на цілість.
globewalldesk

66

Ви можете перевірити, чи є кількість залишку:

var data = 22;

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

Зауважте, якщо ваш вклад також може бути текстом, і ви хочете перевірити спочатку це не так, то ви можете спочатку перевірити тип:

var data = 22;

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

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

3
@Erwinus: запустіть 0 % 1 === 0у консолі. Він повертається trueяк 0 % 1повернення 0.
Nope

Ви спробували це в IE ;-)
Codebeat

1
@Erwinus: 0 % 1повертається 0в режим сумісності IE9, IE8 та IE7.
Nope

Спробуйте це у справжньому старому IE. до того ж це завжди хороший спосіб програмування перевірити наявність нуля і не покладатися на браузер, що робити.
Codebeat

62
@Erwinus: Я думаю, ви переплутали свої факти. Похибка ділення на нуль виникає, коли ви ділите на нуль, а не тоді, коли ділите нуль на число. Нічого не пов’язаного з версією IE взагалі.
Nope


15

По-перше, NaN - це "число" (так, я знаю, що це дивно, просто згорніть його), а не "функція".

Вам потрібно перевірити, чи є тип змінної числом, і щоб перевірити ціле число, я би використовував модуль.

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

2
має бути: попередження (typeof data == 'number' && (data == 0 || data% 1 == 0)); щоб уникнути поділу на нуль.
Codebeat

19
@Erwinus 0% 1 все ще ділиться на 1.
Філ

@Phil, (0 == 0 || 0 % 1 == 0)оцінить до true.
tomekwi

О, до речі 0 % 1 == 0також оцінює true! %це не поділ!
tomekwi

13

Будьте уважні під час використання

число% 1

порожній рядок ('') або булевий (справжній або хибний) повернеться як ціле число. Можливо, ви не хочете цього робити

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

Number.isInteger (дані)

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

вбудувати функцію в браузері. Dosnt підтримує старі браузери

Альтернативи:

Math.round(num)=== num

Однак Math.round () також не вдається для порожнього рядка та булевого типу


8

Щоб перевірити, чи потрібне ціле число, як плакат:

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

повідомлення + перед даними (перетворює рядок у число), а === - для точного.

Ось приклади:

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

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

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

6
Це здається найрозумнішим рішенням для мого випадку (де я не заперечую, якщо це ціле число в рядку). Однак: чому б просто не піти return (+data===parseInt(data))?
Швейцарський містер


6

Найпростішим та найчистішим рішенням до ECMAScript-6 (яке також є достатньо надійним для повернення помилкових, навіть якщо нечислове значення, таке як рядок або нуль, передається функції) буде таким:

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

Наступне рішення також спрацювало, хоча і не настільки елегантно, як вище.

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

Зауважте, що Math.ceil () або Math.floor () можна використовувати однаково добре (замість Math.round ()) у вищевказаній реалізації.

Або в якості альтернативи:

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

Одне досить поширене неправильне рішення:

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

Хоча цей підхід на основі parseInt буде добре працювати для багатьох значень x, як тільки x стане досить великим, він не працюватиме належним чином. Проблема полягає в тому, що parseInt () примушує свій перший параметр до рядка перед розбором цифр. Тому, як тільки число стане достатньо великим, його рядкове представлення буде представлено у експоненціальній формі (наприклад, 1e + 21). Відповідно, parseInt () спробує розібрати 1e + 21, але припинить розбір, коли він досягне символу e, і тому поверне значення 1. Зауважте:

> String(1000000000000000000000)
'1e+21'

> parseInt(1000000000000000000000, 10)
1

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

6

Чому ніхто не згадав Number.isInteger()?

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

Для мене прекрасно працює і вирішує питання з NaNпочатковим номером.


1
Зауважте, що це ES6, тому старші веб-переглядачі (як IE <= 11) не підтримують його. Документи, наведені вище, забезпечують полізаливку.
єпископ

Хто - то робив згадка Number.isInteger(), 3,5 року перед вами: stackoverflow.com/a/27424770/5208540
Alex Stragies

якщо ми збираємося впізнати значення з вхідного сигналу, перевіримо, Number.isInteger завжди поверне помилкове значення, оскільки вхідне значення має рядковий тип даних
Shinigamae

6

У ES6 додано 2 нові методи для Number Object.

У ньому метод Number.isInteger () повертає значення true, якщо аргумент є цілим числом.

Приклад використання:

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

4

Стандарт ECMA-262 6.0 (ES6) включає номер.isInteger функцію .

Для того, щоб додати підтримку старого браузера, я настійно рекомендую використовувати сильне та підтримуване спільнотою рішення:

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

що є чистою бібліотекою поліфілів ES JS .

Зауважте, що для цієї ліб потрібен es5-shim, просто дотримуйтесь README.md.


4

Ви можете спробувати, Number.isInteger(Number(value))якщо це valueможе бути ціле число у рядковій формі, наприклад, var value = "23"і ви хочете, щоб це оцінили true. Уникайте спроб, Number.isInteger(parseInt(value))оскільки це не завжди повертає правильне значення. наприклад, якщо var value = "23abc"ви використовуєтеparseInt реалізацію, вона все одно поверне істину.

Але якщо ви хочете суворо цілих значень, то, ймовірно, Number.isInteger(value)слід зробити свою справу.


1
Зауважте, що IE не підтримується; як сказано тут у документі, я припинив свій сценарій через це, особливо якщо вар, який ви перевіряєте, не визначений
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
Після 29 відповідей можна було б очікувати трохи більше пояснень, щоб ваша відповідь виділялася ...
brasofilo

3

Перевірте, чи змінна дорівнює тій самій змінній, округленій до цілого числа, як це:

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

Ви можете дуже легко вирішити проблему цієї функції з поверненням trueдо NaN, просто змінюючи !=до !==і перевертання ifблоків. Це працює, тому що NaNце єдине значення в JavaScript, яке не дорівнює собі. Наприклад, новий код повинен бутиif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99

3

Крім того, Number.isInteger(). Можливо Number.isSafeInteger(), тут є інший варіант , використовуючи вказаний ES6.

Для Number.isSafeInteger(..)повторного заповнення в браузерах до 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() це найкращий спосіб, якщо ваш браузер підтримує його, якщо ні, я думаю, що існує так багато способів:

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

або:

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

або:

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

або:

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

Тепер ми можемо перевірити результати:

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

Отже, усі ці методи є роботами, але коли число дуже велике, parseInt і ^ оператор не будуть працювати добре.


3

Просто спробуйте:

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

Number.isInteger () підтримується не у всіх версіях браузерів IE.
SKR

2

Ви можете використовувати цю функцію:

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

Він повернеться істинним, навіть якщо значенням є рядок, що містить ціле число.
Отже, результати будуть:

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

2

Мій підхід:

a >= 1e+21Тест може здати лише значення, яке повинно бути числом і дуже великим. Це напевно охопить усі випадки, на відміну від інших рішень, які були запропоновані в цій дискусії.

a === (a|0)Якщо аргумент заданої функції точно (===) такий же, як і побітове перетворення значення, це означає, що аргумент є цілим числом.

a|0поверне 0будь-яке значення, aяке не є числом , і якщо aце дійсно число, воно викреслить що-небудь після десяткової крапки, і 1.0001стане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
Гарна ідея! Мені також подобається, що ви показали свої тести, але, на жаль, це значення не враховує значення String "0".
Джаммер

Гей @vsync, Не навмисно. Я спочатку виступав із заявою, але вирішив повернути його назад, завдяки своєму попередньому коментарю Я, мабуть, випадково двічі натиснув його чи щось.
Джаммер

1

Ви можете використовувати для цього regexp:

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


1

Використовуйте |оператора:

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

Отже, тестова функція може виглядати приблизно так:

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

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

  return true;
};

1

Це вирішить ще один сценарій ( 121. ), крапка в кінці

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

Для позитивних цілих значень без роздільників:

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

Тести 1. якщо не порожні та 2. якщо значення дорівнює результату заміни нецифрового знаку у його значенні.


1

Гаразд мінус, бо мій приклад не описав, тому більше прикладів :):

Я використовую регулярний вираз і метод тесту:

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

Має мінус, ймовірно, тому що тест - це не функція.
imlokesh

@imlokesh, що ти означає "не функція"? oO Я написав, що використовую "метод тестування".
Василь Гутник

@imlokesh немає проблем, я просто запитую U, бо я використовував це у виробництві :), і я думав, ти знайшов помилку :)
Василь Гутник

1

ви також можете спробувати це таким чином

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

або

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

Це призведе до неправильного результату для data=22.5;. Також обидві гілки мають console.log("not an integer"):: S
Colin Breame,

0

Я повинен був перевірити, чи є змінна (рядок або число) цілим числом, і я використав цю умову:

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

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

Деякі з інших відповідей мають подібне рішення (покладайтеся на parseFloatкомбіновані з isNaN), але моя повинна бути більш прямою і самовиясненою.


Редагувати: я з’ясував, що мій метод не працює для рядків, що містять коми (наприклад, "1,2"), і я також зрозумів, що в моєму конкретному випадку я хочу, щоб функція вийшла з ладу, якщо рядок не є дійсним цілим числом (повинен вийти з ладу на будь-якому поплавці , навіть 1,0). Отже ось моя функція 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/

Звичайно, якщо вам дійсно потрібна функція для прийому цілих плавців (1,0 штук), ви завжди можете видалити умову крапки a.indexOf('.') == -1.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.