Как я могу проверить, что число с плавающей точкой или целое число?

718

Как узнать, что число есть floatили integer?

1.25 --> float  
1 --> integer  
0 --> integer  
0.25 --> float
coure2011
источник
48
Я понимаю, что вы спрашиваете здесь, но просто для ясности: <nit-pick>JavaScript не имеет различных целочисленных и числовых типов с плавающей точкой. Каждое число в JavaScript это просто Number. </nit-pick>
Мэтт Болл
4
Является Infinityли целое или нецелое значение для вас? Ответы здесь довольно равномерно распределены на этот счет.
Майк Самуэль,
11
@MikeSamuel Чтобы быть математически точным: поскольку бесконечность не является действительным числом, а все целые числа являются действительными числами, Infinityих нельзя считать целым числом.
rvighne
@rvighne, вопрос задает о "поплавке", а не "реальном". В любом случае, реальные значения не имеют значения, потому что компьютеры могут представлять только вычислимые числа .
Майк Самуэль,
2
@rvighne, я думаю, мы согласны с тем, что тот факт, что бесконечности и NaN не являются действительными числами, означает, что числа с плавающей запятой IEEE-754 не являются подмножеством действительных чисел. Весь численный анализ, основанный на IEEE-754, имеет дело с этим фактом. Что я не понимаю, так это то, как вы думаете, этот факт определяет, как is_integral должен вести себя в отношении кардинальности. Лично я считаю ((x% 1) == 0) хорошим прокси и полностью определен IEEE-754, поэтому нет необходимости спорить о соответствии между различными номерами строк.
Майк Сэмюэл

Ответы:

1257

проверить остаток при делении на 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 Script 2015. Это решение рассматривается в этом ответе .

Kennebec
источник
139
Осторожно, это также будет возвращать верно для пустой строки, строка , представляющая собой целое число, true, false, null, пустой массив, массив , содержащий один целое число, массив , содержащий строку , представляющую собой целое число, а может быть больше.
Дагг Наббит
18
Хороший трюк, но не правильный ответ, так как он не может проверить пустую строку, ""и 1.0 isInt("");&& isInt(1.0);оба результата приводят к trueдемонстрации jsbin.com/elohuq/1/edit
Champ
9
В общем, использование === поощряется вместо == в целом, потому что это приводит к большей безопасности типов и более предсказуемому, унифицированному поведению. Как заявили предыдущие ответчики, этот ответ абсолютно неверен на 100%. Значения null, пустая строка, 1.0 и многие другие все будут неправильно регистрироваться как целые числа (даже с проверкой ===).
Whoblitz
55
Вопрос был в том, как проверить, является ли число целым числом, а не в том, как проверить какое-либо значение.
Кеннебек
25
Много враждебных комментариев о том, как он не проверяет строки. Это не часть вопроса ОП. Если я перейду к SO, чтобы задать вопрос о получении последнего элемента массива, и кто-то ответит function last (array) { return array[array.length - 1]; }, это «просто неправильно» или «Наихудший ответ на SO», потому что он не проверяет, является ли аргумент первым массивом? Да, хорошая практика проверять аргументы, но это ответственность разработчика. SO ответы должны быть короткими и отвечать на вопрос максимально четко.
М Миллер
151

Попробуйте эти функции, чтобы проверить, является ли значение числовым примитивным значением, которое не имеет дробной части и находится в пределах размера того, что может быть представлено как точное целое число.

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

function isInteger(n) {
    return n === +n && n === (n|0);
}
Дагг Наббит
источник
5
хех удивительный эксплойт, он в значительной степени мой ( n===+nдля проверки числовых, n|0для округления), но со встроенными операторами. фанки
Клавдиу
7
@John Hartsock строка никогда не будет числовым значением. Это строка Цель этой функции - проверить, является ли значение числовым значением Javascript, которое не имеет дробной части и находится в пределах размера, который может быть представлен как точное целое число. Если вы хотите проверить строку, чтобы увидеть, содержит ли она последовательность символов, представляющих число, вы должны parseFloat()сначала позвонить .
Заостренный
4
@ Джон Хартсок: он не вернет истину, если не был передан числовой примитив. Я думаю, что это имеет смысл, учитывая названия функций. Все остальное должно быть кандидатом в isString, isBoolean и т. Д., Если такие функции пишутся.
Дагг Наббит
4
@Pointy: числа с плавающей запятой двойной точности могут представлять целочисленные значения с точностью до 2 ^ 53. Таким образом, это зависит от того, спрашивал ли OP о целых числах в математическом смысле (целые числа) или в 32-битном смысле данных. Если это последнее, ваше решение идеально.
djd
8
в javascript побитовые операторы типа |(ИЛИ) работают только со знаком 32-битных целых чисел. OP не указывает, нужно ли проверять подписанные значения int32. Так что это не будет работать с номерами вне диапазона. isInteger(5000000000)вернусь, falseчто неправильно!
Онур Йылдырым
93

Почему не как то так

var isInt = function(n) { return parseInt(n) === n };
warfares
источник
Это на самом деле основа хорошего решения для меня. Мне нужно было разрешить положительные целые числа и запретить числа с плавающей запятой, строки и отрицательные целые числа.
Имран, Великобритания,
4
Это кажется намного лучшим решением, чем другие в этой теме. Может ли сообщество предложить некоторую критику, возможно?
сбиченко
5
var y = 1,00; y === parseInt (y, 10); // это возвращает true для меня, что не совсем то, что мы хотим.
Whoughton
Единственный «недостаток», который я вижу, заключается в том, что данное число nпреобразуется в строку с помощью parseInt. Смотрите MDN . Но я буду использовать это решение. :)
RhinoDevel
2
@ekussberg: Почему это должно возвращать ложь? 1 является инт. и 02, второй аргумент, игнорируется.
Флимзи
89

Существует метод с именем, 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;
};
paperstreet7
источник
Это работает в моем Chrome сейчас тоже и, вероятно, путь в будущем
Dukeatcoding
1
На мой взгляд лучшее решение.
Автомат
1
Это с polyfill является наиболее надежным и простым решением.
Франческо
2
@SergeyPanfilov 12.0 ∈ ℤ.
Константин Ван
1
Я не знаю, изменилась ли спецификация с тех пор, как был дан этот ответ, но учтите, что приведенная выше функция не является правильной для полифилла Number.isInteger. Тем не менее, это правильный polyfill для 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))
Тотемарио
Короче и чуть менее читабельный однострочный:/^[0-9]+$/.test(''+value)
skeggse
3
Не обрабатывает отрицательные целые числа. Вам также не нужен троичный оператор, так как test () возвращает логическое значение. Это должно сделать это:return /^-?\d+$/.test(String(value));
Крис Бартли
@ChrisBartley, спасибо! Я сделал обновление, включая ваши кредиты. Пожалуйста, проверьте, все ли в порядке сейчас.
Марсио Маццукато
19

Вот эффективные функции, которые проверяют, является ли значение числом или его можно безопасно преобразовать в число:

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

И для целых чисел (вернул бы false, если значение является плавающим):

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

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

Спасибо другим постам здесь за предоставление дальнейших идей для оптимизации!

Таль Лирон
источник
3
Эта функция завершается с ошибкой в ​​пустой строке: isNumber ('') имеет значение true.
Джейсон Грут
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
Lukas Liesis
@LukasLiesis не для меня.
doubleOrt
Здесь нет необходимости в любом из операторов строгого равенства.
doubleOrt
isFloat (1563457121531) возвращает false
Aalex Gabi
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) является ложным
Джанго
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 технически является числом с плавающей запятой, хотя ... зависит от варианта использования, я полагаю.
Клаудиу
6

Как насчет этого?

isFloat(num) {
    return typeof num === "number" && !Number.isInteger(num);
}
Goehybrid
источник
Попробуйте console.log(isFloat(1.0));результаты ложные.
Фабиан Пиконе
5

Вот что я использую для целых чисел:

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

Короче, приятно :) Работает постоянно. Это то, что предлагает Дэвид Фланаган, если я не ошибаюсь.

Арман МакХитариан
источник
Мне нравится этот, потому что это короткий, простой ответ, который не опирается на загадочные побитовые операции.
Джим
Почему parseFloat?
DoubleOrt
4

Это действительно зависит от того, чего вы хотите достичь. Если вы хотите «подражать» языкам со строгой типизацией, я советую вам не пытаться. Как уже упоминалось, все числа имеют одинаковое представление (один и тот же тип).

Используя что-то вроде Клаудиу, при условии:

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

что выглядит хорошо для здравого смысла, но в чем-то вроде C вы получите false

gblazex
источник
4

Любое число с плавающей точкой с нулевой десятичной частью (например, 1,0, 12,00, 0,0) неявно приводится к Integer, поэтому невозможно проверить, являются ли они Float или нет.

Майк Манчини
источник
4
!!(24%1) // false
!!(24.2%1) // true
Виктор Дакалов
источник
!!(24.0%1)ложно
Rohmer
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) }
SpYk3HH
источник
isInteger (12.0) верно
Джанго
3
var isInt = function (n) { return n === (n | 0); };

Не было случая, чтобы это не делало работу.

ankr
источник
эй, извините, почему это возвращает ложь? console.log (IsInt (7932938942839482938));
itsme
4
Потому что это превышает MaxInt.
ankr
но вы можете установить максимальную длину Int Нету? что если я не знаю, длина int возвращается?
itsme
1
@ekussberg Да, потому что 2является целым числом и 23считается вторым аргументом функции. В javascript десятичные дроби пишутся с использованием точки в качестве разделителя - так и должно быть 2.23.
ankr
1
Или это отличная возможность узнать о побитовых операциях. От этого вы получите много пользы.
ankr
2

ЭТО ОКОНЧАТЕЛЬНЫЙ КОД ДЛЯ ПРОВЕРКИ ОБА И INT

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;   
}   
Кен Ле
источник
Это проверяет только число с плавающей запятой, если 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');
}
Vitim.us
источник
Целое число не является числом с плавающей точкой? Новости для меня.
Мартен Бодьюс
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 цифр "должно быть достаточно для всех", чтобы процитировать классический :)

dkellner
источник
Это хорошо, если вам нужно проверять только целые числа (из математического POV), но если вы хотите убедиться, что они действительно работают как целые числа (из вычислительного POV), это будет неправильно для огромных чисел. Смотрите этот комментарий .
Дагг Наббит
Ммммммм ... Почему ты так думаешь? Я имею в виду, если parseInt возвращает что-то, и оно кажется равным самой переменной, вы можете быть уверены, что ваш n действительно работает как целое число. Я обнаружил, что 99999999999999999999 (то есть, 20 раз «9») - это число, в то время как добавление еще одной «9» приводит к сбою parseInt (возвращая 1). Это может зависеть от браузера; однако, ДА, есть предел, и НЕТ, что бы ни было за пределами этого предела, не вернет истину для проверки выше.
dkellner
Я имею в виду, что побитовые операторы (которые обрабатывают числа как 32-битные целые числа) не дадут ожидаемых результатов для чисел, которые не могут быть представлены как 32-битные целые числа, поэтому эти числа не должны идентифицироваться как целые числа. Это соответствует тому, как Number.isIntegerработает предлагаемый .
Dagg Nabbit
Что-то может быть истинным целым числом без сохранения одним конкретным способом. Я понимаю вашу точку зрения, но целые числа являются целыми числами, потому что они не имеют дробной части и могут быть произвольно добавлены / вычтены без получения плавающих результатов. Если вы рассматриваете числа как битовые поля, вы предполагаете что-то о том, как они хранятся, что, на мой взгляд, практически работает, но не на 100% надежно. Если вы ищете «целое число, хранящееся определенным образом», то я не уверен, что есть однострочный тест, который можно безопасно использовать на всех платформах.
dkellner
Числа, которые могут быть выражены как 32-битные целые числа, работают на 100% надежно с побитовыми операторами. Вы не «предполагаете что-либо о том, как они хранятся»; числа преобразуются в 32-разрядные целые числа с двоичными числами второго порядка со знаком в соответствии со спецификацией. Числа, которые не могут быть представлены в этом формате, не должны рассматриваться как целые числа. Опять же, это соответствует тому, как Number.isIntegerработает. Однострочный тест, n === (n | 0)как показано в другом ответе.
Дагг Наббит
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;
}
neoneye
источник
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
   }
}
toddsalpen
источник
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

Возможно, это не так эффективно, как% answer, что не позволяет вам сначала преобразовать строку, но я еще не видел, чтобы кто-нибудь опубликовал ее, так что вот еще один вариант, который должен работать нормально:

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
jnthnjns
источник
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

Мне нравится эта маленькая функция, которая будет возвращать true для положительных и отрицательных целых чисел:

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 () возвращает false (и, опять же, получает отрицание).

Если вы хотите только натуральные числа, есть такой вариант:

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», что оценивает false. Между тем, isPositiveInt (-1) приводит к тому, что isNaN () оценивает «0-1», что оценивает true. Мы отрицаем возвращаемое значение, и это дает нам то, что мы хотим. isNegativeInt () работает аналогично, но без отрицательного значения, возвращаемого isNaN ().

Редактировать:

Моя оригинальная реализация также возвращала бы true для массивов и пустых строк. Эта реализация не имеет такого недостатка. Он также имеет преимущество возврата рано, если 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!

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

Из 10 протестированных функций те, которые действительно соответствуют требованиям OP, [1,3,5,6,8,9]

KeMBro2012
источник
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'если вы хотите исключить строки.

Мирек Русин
источник