Як я можу перевірити, чи число є плаваючим чи цілим?


717

Як знайти, що число є floatабо integer?

1.25 --> float  
1 --> integer  
0 --> integer  
0.25 --> float

47
Я розумію, що ви тут запитуєте, але просто для того, щоб було зрозуміло: <nit-pick>JavaScript не має різних цілочисельних і плаваючих числових типів. Кожне число в JavaScript - це лише "a" Number. </nit-pick>
Метт-бал

4
Чи Infinityє ціле чи не ціле значення, наскільки ви стурбовані? Відповіді тут досить рівномірно розподілені на цей рахунок.
Майк Самуель

11
@MikeSamuel Щоб бути математично точним: оскільки нескінченність не є дійсним числом, а всі цілі числа - це дійсні числа, Infinityне можна вважати цілим числом.
rvighne

@rvighne, Питання задається про "пливуть", а не "реально". У будь-якому випадку реальні значення не мають значення, оскільки комп'ютери можуть представляти лише обчислювані числа .
Майк Самуель

2
@rvighne, я думаю, ми погоджуємось, що той факт, що нескінченності та NaN не є реальними числами, означає, що IEEE-754 плаває не є підмножиною реальних чисел. Весь чисельний аналіз на основі IEEE-754 має справу з цим фактом. Що я не розумію - це, як ви вважаєте, цей факт визначає, як is_integral повинен поводити кардинальності Wrt. Особисто я думаю, ((x% 1) == 0) є хорошим проксі-сервером і повністю визначений IEEE-754, тому не потрібно сперечатися про відповідність між різними числовими рядками.
Майк Самуель

Відповіді:


1255

перевірити на залишок при діленні на 1:

function isInt(n) {
   return n % 1 === 0;
}

Якщо ви не знаєте, що аргумент - це число, вам потрібні два тести:

function isInt(n){
    return Number(n) === n && n % 1 === 0;
}

function isFloat(n){
    return Number(n) === n && n % 1 !== 0;
}

Оновлення 2019 року через 5 років після написання цієї відповіді рішення було стандартизоване у сценарії ECMA 2015. Це рішення охоплене у цій відповіді .


138
Обережно, це також буде повертати вірно для порожнього рядка, рядок , що представляє собою ціле число, true, false, null, порожній масив, масив , що містить один ціле число, масив , що містить рядок , що представляє собою ціле число, а може бути більше.
Dagg Nabbit

17
Хороший трюк, але не правильна відповідь, оскільки не вдається перевірити порожній рядок ""і 1.0 isInt("");&& isInt(1.0);як результат, trueпобачити цю демонстрацію jsbin.com/elohuq/1/edit
Champ

9
Іна, використання === рекомендується над == загалом, оскільки це призводить до більшої безпеки та більш передбачуваної, рівномірної поведінки. Як зазначали попередні відповіді, ця відповідь абсолютно, на 100% неправильна. Значення null, порожній рядок, 1.0 та численні інші будуть зареєстровані неправильно як цілі числа (навіть за допомогою пункту ===).
whoblitz

54
Питання полягало в тому, як перевірити, чи є число цілим числом, а не як перевірити будь-яке значення.
kennebec

24
Дуже багато ворожих коментарів щодо того, як це не підтверджує рядки. Це не є питанням ОП. Якщо я переходжу до SO, щоб задати питання про отримання останнього елемента масиву, і хтось відповість function last (array) { return array[array.length - 1]; }, чи це "просто неправильно" або "Найгірша відповідь на SO", тому що він не перевіряє, чи аргумент спочатку є масивом? Так, хороша практика перевірки аргументів, але це відповідальність розробника. Відповіді ТА повинні бути короткими і безпосередньо відповідати на питання якомога чіткіше.
М Міллер

150

Спробуйте скористатися цими функціями, щоб перевірити, чи є значення примітивним числом, яке не має дробової частини і чи не в межах граничних розмірів того, що може бути представлено у вигляді точного цілого числа.

function isFloat(n) {
    return n === +n && n !== (n|0);
}

function isInteger(n) {
    return n === +n && n === (n|0);
}

5
heh awesom exploit, це в значній мірі ( n===+nперевірити чисельність, n|0круглий), але з вбудованими операторами. funky
Клавдіу

7
@John Hartsock рядок ніколи не буде числовим значенням. Це струна. Суть цієї функції полягає в тому, щоб перевірити, чи є значення числовим значенням Javascript, яке не має дробової частини і знаходиться в межах розміру того, що може бути представлено у вигляді точного цілого числа. Якщо ви хочете перевірити рядок, щоб побачити, чи містить він послідовність символів, що представляють число, вам слід зателефонувати parseFloat()спочатку.
Pointy

4
@John Hartsock: вона не поверне істину, якщо не буде передано примітив номер. Я думаю, що це має сенс, враховуючи назви функцій. Усі інші повинні бути кандидатом на isString, isBoolean тощо, якщо такі функції записуються.
Dagg Nabbit

4
@Pointy: поплавці подвійної точності можуть представляти цілі значення точно до 2 ^ 53. Отже, це залежить, якщо ОП запитували про цілі числа в математичному сенсі (цілі числа) або в 32-бітовому сенсі даних. Якщо це останнє, ваше рішення ідеальне.
дед

8
у javascript, побітові оператори типу |(АБО) працюють лише за підписаними 32-бітовими цілими числами. В OP не зазначено, якщо мета - перевірити наявність підписаних значень int32. Таким чином, це не буде працювати з номерами поза діапазоном. isInteger(5000000000)повернеться, falseщо неправильно!
Onur Yıldırım

93

Чому б не щось подібне:

var isInt = function(n) { return parseInt(n) === n };

Це насправді серцевина хорошого рішення для мене. Мені потрібно дозволити додатні цілі числа та заборонити поплавці, рядки та від’ємні цілі числа.
Імран-Великобританія

4
Це здається набагато кращим рішенням, ніж інші в цій темі. Чи може громада запропонувати певну критику?
sbichenko

5
var y = 1,00; y === parseInt (y, 10); // це повертає істину для мене, що насправді не є тим, чого ми хочемо.
Уоттон

Єдиний "недолік", який я бачу, - це те, що задане число nперетворюється в рядок на parseInt. Див. MDN . Але я буду використовувати це рішення. :)
RhinoDevel

2
@ekussberg: Навіщо це повертати помилкове? 1 - int. і 02, другий аргумент, ігнорується.
Flimzy

88

Існує метод, Number.isInteger()який називається, який зараз реалізується у всьому, крім IE. MDN також забезпечує полісистему для інших браузерів:

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

Однак для більшості випадків використання вам краще використовувати те, Number.isSafeInteger що також перевіряє, чи є значення настільки високим / низьким, що будь-які десяткові знаки в будь-якому разі були б втрачені. MDN також має поліфіл для цього. (Також вам потрібен isIntegerполіліф вище.)

if (!Number.MAX_SAFE_INTEGER) {
    Number.MAX_SAFE_INTEGER = 9007199254740991; // Math.pow(2, 53) - 1;
}
Number.isSafeInteger = Number.isSafeInteger || function (value) {
   return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
};

Це працює і в моєму Chrome, і, ймовірно, шлях у майбутньому
Dukeatcoding

1
На мій погляд, найкраще рішення.
Automatico

1
Це за допомогою полісистеми є найбільш надійним і простим рішенням.
Франческо Паса

2
@SergeyPanfilov 12.0 ∈ ℤ.
Константин Ван

1
Мені невідомо, чи змінилася специфіка з моменту надання цієї відповіді, але зауважте, що вищевказана функція не є правильним для заповнення Number.isInteger. Це, однак, правильна поліфіл для Number.isSafeInteger. Number.isIntegerне слід перевіряти, чи є число "безпечним цілим числом". Дивіться на MDN: isInteger та isSafeInteger .
nunocastromartins

33

Ви можете використовувати простий регулярний вираз:

function isInt(value) {

    var er = /^-?[0-9]+$/;

    return er.test(value);
}

Або ви також можете використовувати наведені нижче функції, відповідно до ваших потреб. Вони розроблені Проектом PHPJS .

is_int() => Перевірте, чи змінний тип є цілим числом, чи вміст його цілим

is_float() => Перевірте, чи є змінний тип float і чи є його вміст float

ctype_digit() => Перевірте, чи тип змінної є рядковим і чи вміст має лише десяткових цифр

Оновлення 1

Тепер він перевіряє і негативні цифри, дякую за коментар @ChrisBartley !


1
Ідеально підходить для тестування простих непідписаних цілих чисел.
дотемаріо

7
Один лайнер:/^[0-9]+$/.test(String(value))
tothemario

Коротший і трохи менш читабельний одноколісний:/^[0-9]+$/.test(''+value)
skeggse

3
Не обробляє негативні цілі числа. Потрійного оператора вам також не потрібно, оскільки test () повертає булеву форму. Це слід зробити так:return /^-?\d+$/.test(String(value));
Кріс Бартлі

@ChrisBartley, спасибі! Я зробив оновлення, включаючи ваші кредити. Перевірте, чи зараз все в порядку.
Marcio Mazzucato

19

Ось ефективні функції, які перевіряють, чи є значення числом, чи їх можна безпечно перетворити на число:

function isNumber(value) {
    if ((undefined === value) || (null === value)) {
        return false;
    }
    if (typeof value == 'number') {
        return true;
    }
    return !isNaN(value - 0);
}

А для цілих чисел (поверне помилковим, якщо значенням є float):

function isInteger(value) {
    if ((undefined === value) || (null === value)) {
        return false;
    }
    return value % 1 == 0;
}

Ефективність тут полягає в тому, що parseInt (або parseNumber) уникають, коли значення вже є числом. Обидві функції розбору завжди перетворюються на рядок, а потім намагаються проаналізувати цей рядок, що було б марно, якщо значення вже є числом.

Дякуємо іншим публікаціям тут за надані подальші ідеї для оптимізації!


3
Ця функція не спрацьовує у порожній рядку: isNumber ('') вірно.
Джейсон Гроут

14
function isInteger(x) { return typeof x === "number" && isFinite(x) && Math.floor(x) === x; }
function isFloat(x) { return !!(x % 1); }

// give it a spin

isInteger(1.0);        // true
isFloat(1.0);          // false
isFloat(1.2);          // true
isInteger(1.2);        // false
isFloat(1);            // false
isInteger(1);          // true    
isFloat(2e+2);         // false
isInteger(2e+2);       // true
isFloat('1');          // false
isInteger('1');        // false
isFloat(NaN);          // false
isInteger(NaN);        // false
isFloat(null);         // false
isInteger(null);       // false
isFloat(undefined);    // false
isInteger(undefined);  // false

4
Мабуть, плавці, які закінчуються на .0, автоматично передаються в Int в JavaScript.

не вдалося с 1.2. Завжди перевіряйте числові функції з 0,1 0,2 0,3
Лукас Ліесіс

@LukasLiesis не для мене.
подвійнийОкт

Тут немає необхідності в жодному з чітких операторів рівності.
подвійнийОкт

isFloat (1563457121531) повертається помилково
Алекс Габі

9
function isInt(n) 
{
    return n != "" && !isNaN(n) && Math.round(n) == n;
}
function isFloat(n){
    return n != "" && !isNaN(n) && Math.round(n) != n;
}

працює для всіх випадків.


2
+1 Це добре. isInt('1')повертається trueяк очікувалося (принаймні для мене). Weird досить, хоча, це повертається trueдо isInt([5])а. Для мене це не мало значення, але можливо для вас, тож, подбайте.
acdcjunior

2
isFloat (12.0) false
django

6

Як згадували інші, у вас є лише дубль у JS. Отже, як визначити число, яке є цілим числом? Просто перевірте, чи округлене число дорівнює самому собі:

function isInteger(f) {
    return typeof(f)==="number" && Math.round(f) == f;
}
function isFloat(f) { return typeof(f)==="number" && !isInteger(f); }

3
Ви можете перевірити, чи є значення числовим ... isFloat('abc')повертаєтьсяtrue
Dagg Nabbit

isFloat(NaN) // true
shime

@shime: Хороший улов. NaN - це технічно число з плаваючою комою, хоча ... я думаю, що це стосується випадку використання.
Клавдіу


5

Ось що я використовую для цілих чисел:

Math.ceil(parseFloat(val)) === val

Коротко, приємно :) Працює весь час. Ось що пропонує Девід Фланаган, якщо я не помиляюся.


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

Чому parseFloat?
подвійнийОкт

4

Це дійсно залежить від того, чого ви хочете досягти. Якщо ви хочете "імітувати" сильно набрані мови, то я пропоную вам не намагатися. Як згадували інші, всі номери мають однакове представлення (одного типу).

Використовуючи щось на кшталт Клавдіу, передбачено:

isInteger( 1.0 ) -> правда

що виглядає чудово для здорового глузду, але в чомусь подібному C ви отримаєте false


4

Будь-яке число Float з нульовою десятковою частиною (наприклад, 1,0, 12,00, 0,0) неявно передається цілому, тому неможливо перевірити, чи вони плаваючі чи ні.



3

Це дійсно не повинно бути таким складним. Чисельне значення еквівалентів parseFloat () та parseInt () буде цілим числом. Таким чином, ви можете зробити так:

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

Тоді

if (isInt(x)) // do work

Це також дозволить перевірити рядок і, таким чином, не є суворим. Якщо ви хочете вирішити сильний тип (він же не працює з рядками):

function is_int(value){ return !isNaN(parseInt(value * 1) }

isInteger (12.0) вірно
django

3
var isInt = function (n) { return n === (n | 0); };

У мене не було випадку, коли це не зробило б роботу.


Ей вибачте, чому це повертається помилково? console.log (isInt (7932938942839482938));
itme

4
Тому що це перевищує MaxInt.
ankr

але ви можете встановити внутрішню максимальну довжину nope? Що робити, якщо я не знаю, повертається довжина int?
itsme

1
@ekussberg Так, тому що 2це ціле число і 23вважається другим аргументом функції. У javascript децималі записуються, використовуючи крапку як роздільник - так і має бути 2.23.
ankr

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

2

ЦЕ КІНЦЕВИЙ КОД ЗА ПЕРЕВІРТАННЯ ВІД І ПЛАТУ

function isInt(n) { 
   if(typeof n == 'number' && Math.Round(n) % 1 == 0) {
       return true;
   } else {
       return false;
   }
} 

АБО

function isInt(n) {   
   return typeof n == 'number' && Math.Round(n) % 1 == 0;   
}   

Це лише тести на float, якщо n виявиться числом
hacklikecrack

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

function isFloat(n) {
   return ((typeof n==='number')&&(n%1!==0));
}

function isNumber(n) {
   return (typeof n==='number');
}

Ціле число не є плаваючою? Новини для мене.
Maarten Bodewes

2

Це просто так:

if( n === parseInt(n) ) ...

Спробуйте це в консолі:

x=1;
x===parseInt(x); // true
x="1";
x===parseInt(x); // false
x=1.1;
x===parseInt(x); // false, obviously

// BUT!

x=1.0;
x===parseInt(x); // true, because 1.0 is NOT a float!

Це бентежить багато людей. Щоразу, коли щось є .0, це вже не поплавок. Це ціле число. Або ви можете просто назвати це "числовою річчю", оскільки немає чіткого розрізнення, як тоді в C. Добрі старі часи.

В основному, все, що ви можете зробити, це перевірити на ціле число, прийнявши той факт, що 1.000 є цілим числом.

Цікава сторона

Був коментар про величезну кількість. Величезні цифри означають, що НЕ існує проблеми для цього підходу; всякий раз, коли parseInt не в змозі обробити число (бо воно занадто велике), воно поверне щось інше, ніж фактичне значення, тому тест поверне FALSE. Це добре, тому що якщо ви вважаєте щось "числом", ви зазвичай очікуєте, що JS зможе обчислити його - так, так, числа обмежені, і parseInt врахує це , висловивши це так.

Спробуйте це:

<script>

var a = 99999999999999999999;
var b = 999999999999999999999; // just one more 9 will kill the show!
var aIsInteger = (a===parseInt(a))?"a is ok":"a fails";
var bIsInteger = (b===parseInt(b))?"b is ok":"b fails";
alert(aIsInteger+"; "+bIsInteger);

</script>

У моєму браузері (IE8) це повертає "a нормально; b виходить з ладу", що саме через величезну кількість b. Обмеження може бути різним, але, мабуть, 20 цифр "комусь вистачить", цитую класика :)


Це добре, якщо вам потрібно лише перевірити цілісні числа (з математики POV), але якщо ви хочете переконатися, що вони насправді працюють як цілі числа (з обчислювальної POV), це буде неправильним для величезних чисел. Дивіться цей коментар .
Dagg Nabbit

Ммммммм ... Чому ти так вважаєш? Я маю на увазі, якщо parseInt повертає щось, і воно здається рівним самій змінній, ви можете бути впевнені, що ваш n справді працює як ціле число. Я виявив, що 99999999999999999999 (тобто в 20 разів "9") - це число, в той час як додавання ще одного "9" робить синтаксичний розбір (повернення 1). Це може бути залежно від браузера; однак ТАК, існує обмеження, і НІ, що б не було, цей показник не повернеться істинним для перевірки вище.
dkellner

Я маю на увазі те, що побітові оператори (які розглядають числа як 32-бітові вставки) не дадуть очікуваних результатів для чисел, які не можуть бути представлені як 32-бітові вставки, тому ці числа не повинні ідентифікуватися як ints. Це відповідає тому, як Number.isIntegerпрацює запропоноване .
Dagg Nabbit

Щось може бути справжнім цілим числом, не зберігаючи певний спосіб. Я бачу вашу думку, але цілі числа є цілими числами, оскільки вони не мають дробової частини, і їх можна додавати / віднімати довільно, не отримуючи результатів з плаваючою формою. Якщо ви розглядаєте числа як бітфілди, ви гадаєте, що вони зберігаються, що, на мою думку, є практично працюючим, але не 100% надійним способом. Якщо ви шукаєте "ціле число, яке зберігається певним чином", я не впевнений, що існує однолінійний тест, який ви можете сміливо використовувати на всіх платформах.
dkellner

Числа, які можуть бути виражені 32-бітовими входами, на 100% надійно працюють з побітними операторами. Ви не «припускаєте нічого про те, як вони зберігаються»; номери перетворюються на підписані 32-бітні цілі числа великого ендіана двох за специфікацією. Числа, які не можуть бути представлені в цьому форматі, не повинні вважатися цілими числами. Знову ж таки, це відповідає тому, як Number.isIntegerпрацює. Тест по одному рядку, n === (n | 0)як показано в іншій відповіді.
Dagg Nabbit

2

Це рішення спрацювало на мене.

<html>
<body>
  <form method="post" action="#">
    <input type="text" id="number_id"/>
    <input type="submit" value="send"/>
  </form>
  <p id="message"></p>
  <script>
    var flt=document.getElementById("number_id").value;
    if(isNaN(flt)==false && Number.isInteger(flt)==false)
    {
     document.getElementById("message").innerHTML="the number_id is a float ";
    }
   else 
   {
     document.getElementById("message").innerHTML="the number_id is a Integer";
   }
  </script>
</body>
</html>

1

Для цілих чисел я використовую це

function integer_or_null(value) {
    if ((undefined === value) || (null === value)) {
        return null;
    }
    if(value % 1 != 0) {
        return null;
    }
    return value;
}

1

У сценарії Java всі числа є такими internally 64 bit floating pointж, як у подвійному у Java. У javascript немає різних типів, всі представлені типом number. Отже, ви не зможете зробити instanceofперевірку. Однак ви можете використовувати наведені вище рішення, щоб дізнатись, чи є це дробовим числом. Дизайнери сценарію java відчували себе одним типом, вони можуть уникнути численних помилок у ролях типу.


1

Інколи об'єкти Number не дозволяють використовувати прямий оператор мод (%), якщо ви стикаєтеся з цим випадком, ви можете використовувати це рішення.

if(object instanceof Number ){
   if( ((Number) object).doubleValue() % 1 == 0 ){
      //your object is an integer
   }
   else{
      //your object is a double
   }
}

1

Спробувавши деякі відповіді тут, я закінчив написання цього рішення. Це також працює з числами в рядку.

function isInt(number) {
    if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return !(number - parseInt(number));
}

function isFloat(number) {
    if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return number - parseInt(number) ? true : false;
}

    var tests = {
        'integer' : 1,
        'float' : 1.1,
        'integerInString' : '5',
        'floatInString' : '5.5',
        'negativeInt' : -345,
        'negativeFloat' : -34.98,
        'negativeIntString' : '-45',
        'negativeFloatString' : '-23.09',
        'notValidFalse' : false,
        'notValidTrue' : true,
        'notValidString' : '45lorem',
        'notValidStringFloat' : '4.5lorem',
        'notValidNan' : NaN,
        'notValidObj' : {},
        'notValidArr' : [1,2],
    };

    function isInt(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return !(number - parseInt(number));
    }
    
    function isFloat(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return number - parseInt(number) ? true : false;
    }

    function testFunctions(obj) {
        var keys = Object.keys(obj);
        var values = Object.values(obj);

        values.forEach(function(element, index){
            console.log(`Is ${keys[index]} (${element}) var an integer? ${isInt(element)}`);
            console.log(`Is ${keys[index]} (${element}) var a float? ${isFloat(element)}`);
        });
    }

    testFunctions(tests);


0

Це, можливо, не настільки ефективно, як відповідь%, що заважає вам спочатку перетворитись на рядок, але я ще не бачив, щоб хтось розмістив її, тому ось ще один варіант, який повинен працювати добре:

function isInteger(num) {
    return num.toString().indexOf('.') === -1;
}

Хороший підхід ІМХО
Сергій Панфілов

Я додам, що метод ES6 включає () робить цю відповідь ще простішою
Axle

0

Для тих, хто цікавиться, за допомогою Benchmark.js я перевірив найбільш відповідні відповіді (і ту, яку опублікував сьогодні) на цій публікації, ось мої результати:

var n = -10.4375892034758293405790;
var suite = new Benchmark.Suite;
suite
    // kennebec
    .add('0', function() {
        return n % 1 == 0;
    })
    // kennebec
    .add('1', function() {
        return typeof n === 'number' && n % 1 == 0;
    })
    // kennebec
    .add('2', function() {
        return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
    })

    // Axle
    .add('3', function() {
        return n.toString().indexOf('.') === -1;
    })

    // Dagg Nabbit
    .add('4', function() {
        return n === +n && n === (n|0);
    })

    // warfares
    .add('5', function() {
        return parseInt(n) === n;
    })

    // Marcio Simao
    .add('6', function() {
        return /^-?[0-9]+$/.test(n.toString());
    })

    // Tal Liron
    .add('7', function() {
        if ((undefined === n) || (null === n)) {
            return false;
        }
        if (typeof n == 'number') {
            return true;
        }
        return !isNaN(n - 0);
    });

// Define logs and Run
suite.on('cycle', function(event) {
    console.log(String(event.target));
}).on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').pluck('name'));
}).run({ 'async': true });

0 x 12,832,357 ops/sec ±0.65% (90 runs sampled)
1 x 12,916,439 ops/sec ±0.62% (95 runs sampled)
2 x 2,776,583 ops/sec ±0.93% (92 runs sampled)
3 x 10,345,379 ops/sec ±0.49% (97 runs sampled)
4 x 53,766,106 ops/sec ±0.66% (93 runs sampled)
5 x 26,514,109 ops/sec ±2.72% (93 runs sampled)
6 x 10,146,270 ops/sec ±2.54% (90 runs sampled)
7 x 60,353,419 ops/sec ±0.35% (97 runs sampled)

Fastest is 7 Tal Liron

0

Ось мій код. Він перевіряє, чи не є порожнім рядком (який інакше пройде), а потім перетворює його в цифровий формат. Тепер, залежно від того, чи ви хочете, щоб "1.1" дорівнювало 1.1, це може бути, а може і не бути тим, що ви шукаєте.

var isFloat = function(n) {
    n = n.length > 0 ? Number(n) : false;
    return (n === parseFloat(n));
};
var isInteger = function(n) {
    n = n.length > 0 ? Number(n) : false;
    return (n === parseInt(n));
};

var isNumeric = function(n){

   if(isInteger(n) || isFloat(n)){
        return true;
   }
   return false;

};

0

Мені подобається ця маленька функція, яка поверне істину як для позитивних, так і для негативних цілих чисел:

function isInt(val) {
    return ["string","number"].indexOf(typeof(val)) > -1 && val !== '' && !isNaN(val+".0");
}

Це працює, тому що 1 або "1" стає "1,0", що isNaN () повертає помилкове значення (яке ми потім заперечуємо і повертаємо), але 1,0 або "1,0" стає "1,0,0", а "рядок" стає "рядком". 0 ", жодне з яких не є числами, тому isNaN () повертає помилкові (і, знову ж таки, заперечується).

Якщо ви хочете лише додатні цілі числа, є такий варіант:

function isPositiveInt(val) {
    return ["string","number"].indexOf(typeof(val)) > -1 && val !== '' && !isNaN("0"+val);
}

або для від’ємних цілих чисел:

function isNegativeInt(val) {
    return `["string","number"].indexOf(typeof(val)) > -1` && val !== '' && isNaN("0"+val);
}

isPositiveInt () працює, переміщуючи з'єднаний числовий рядок перед значенням, яке перевіряється. Наприклад, isPositiveInt (1) призводить до того, що isNaN () оцінює "01", що оцінює помилку. Тим часом, isPositiveInt (-1) призводить до того, що isNaN () оцінює "0-1", що оцінює істину. Ми заперечуємо повернене значення і це дає нам те, що ми хочемо. isNegativeInt () працює аналогічно, але без заперечення значення повернення isNaN ().

Редагувати:

Моя оригінальна реалізація також поверне справжнє для масивів та порожніх рядків. Цей недолік не має цього дефекту. Це також має перевагу повернення достроково, якщо val не є рядком або числом, або якщо це порожній рядок, що робить його швидшим у цих випадках. Ви можете додатково змінити його, замінивши перші два пункти на

typeof(val) != "number"

якщо ви хочете відповідати лише буквальним числам (а не рядкам)

Редагувати:

Я поки не можу публікувати коментарі, тому я додаю це до своєї відповіді. Тест, розміщений @Asok, дуже інформативний; однак найшвидша функція не відповідає вимогам, оскільки вона також повертає TRUE для поплавків, масивів, булевих і порожніх рядків.

Я створив наступний тестовий набір, щоб перевірити кожну з функцій, додавши також свою відповідь до списку (функція 8, яка розбирає рядки, і функція 9, яка ні):

funcs = [
    function(n) {
        return n % 1 == 0;
    },
    function(n) {
        return typeof n === 'number' && n % 1 == 0;
    },
    function(n) {
        return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
    },
    function(n) {
        return n.toString().indexOf('.') === -1;
    },
    function(n) {
        return n === +n && n === (n|0);
    },
    function(n) {
        return parseInt(n) === n;
    },
    function(n) {
        return /^-?[0-9]+$/.test(n.toString());
    },
    function(n) {
        if ((undefined === n) || (null === n)) {
            return false;
        }
        if (typeof n == 'number') {
            return true;
        }
        return !isNaN(n - 0);
    },
    function(n) {
        return ["string","number"].indexOf(typeof(n)) > -1 && n !== '' && !isNaN(n+".0");
    }
];
vals = [
    [1,true],
    [-1,true],
    [1.1,false],
    [-1.1,false],
    [[],false],
    [{},false],
    [true,false],
    [false,false],
    [null,false],
    ["",false],
    ["a",false],
    ["1",null],
    ["-1",null],
    ["1.1",null],
    ["-1.1",null]
];

for (var i in funcs) {
    var pass = true;
    console.log("Testing function "+i);
    for (var ii in vals) {
        var n = vals[ii][0];
        var ns;
        if (n === null) {
            ns = n+"";
        } else {
            switch (typeof(n)) {
                case "string":
                    ns = "'" + n + "'";
                    break;
                case "object":
                    ns = Object.prototype.toString.call(n);
                    break;
                default:
                    ns = n;
            }
            ns = "("+typeof(n)+") "+ns;
        }

        var x = vals[ii][1];
        var xs;
        if (x === null) {
            xs = "(ANY)";
        } else {
            switch (typeof(x)) {
                case "string":
                    xs = "'" + n + "'";
                    break;
                case "object":
                    xs = Object.prototype.toString.call(x);
                    break;
                default:
                    xs = x;
            }
            xs = "("+typeof(x)+") "+xs;
        }

        var rms;
        try {
            var r = funcs[i](n);
            var rs;
            if (r === null) {
                rs = r+"";
            } else {
                switch (typeof(r)) {
                    case "string":
                        rs = "'" + r + "'";
                        break;
                    case "object":
                        rs = Object.prototype.toString.call(r);
                        break;
                    default:
                        rs = r;
                }
                rs = "("+typeof(r)+") "+rs;
            }

            var m;
            var ms;
            if (x === null) {
                m = true;
                ms = "N/A";
            } else if (typeof(x) == 'object') {
                m = (xs === rs);
                ms = m;
            } else {
                m = (x === r);
                ms = m;
            }
            if (!m) {
                pass = false;
            }
            rms = "Result: "+rs+", Match: "+ms;
        } catch (e) {
            rms = "Test skipped; function threw exception!"
        }

        console.log("    Value: "+ns+", Expect: "+xs+", "+rms);
    }
    console.log(pass ? "PASS!" : "FAIL!");
}

Я також повторно оцінив функцію № 8, додану до списку. Я не публікую результат, оскільки вони трохи бентежать (наприклад, ця функція НЕ швидка) ...

Результати (скорочені - я видалив успішні тести, оскільки результат досить тривалий) результати такі:

Testing function 0
Value: (object) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) false, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: null, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
FAIL!

Testing function 1
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 2
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 3
Value: (object) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (object) false, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Object], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: null, Expect: (boolean) false, Test skipped; function threw exception!
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) 'a', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
FAIL!

Testing function 4
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 5
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 6
Value: null, Expect: (boolean) false, Test skipped; function threw exception!
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 7
Value: (number) 1.1, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (number) -1.1, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (object) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Object], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) true, Match: N/A
FAIL!

Testing function 8
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 9
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

У мене залишилися збої, щоб ви могли бачити, де кожна функція відмовляється, і (string) '#' тестує, щоб ви могли бачити, як кожна функція обробляє цілочисельні та плаваючі значення в рядках, оскільки деякі можуть хотіти, щоб вони розбиралися як числа, а деякі не можна.

З 10 перевірених функцій ті, які фактично відповідають вимогам ОП, [1,3,5,6,8,9]


0

Умова для плаваючої перевірки:

if (lnk.value == +lnk.value && lnk.value != (lnk.value | 0)) 

Умова для перевірки цілого числа:

if (lnk.value == +lnk.value && lnk.value == (lnk.value | 0)) 

Сподіваюся, це може бути корисним.


0
function int(a) {
  return a - a === 0 && a.toString(32).indexOf('.') === -1
}

function float(a) {
  return a - a === 0 && a.toString(32).indexOf('.') !== -1
}

Ви можете додати, typeof a === 'number'якщо хочете виключити рядки.

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