Как мне проверить, что число бесконечно?


95

У меня есть серия вычислений Javascript, которые (только в IE) показывают бесконечность в зависимости от выбора пользователя.

Как остановить появление слова Infinityи, например, показать 0.0вместо него?

Ответы:


176
if (result == Number.POSITIVE_INFINITY || result == Number.NEGATIVE_INFINITY)
{
    // ...
}

isFiniteВместо этого вы можете использовать эту функцию, в зависимости от того, как вы хотите лечить NaN. isFiniteвозвращается, falseесли ваш номер POSITIVE_INFINITY, NEGATIVE_INFINITYили NaN.

if (isFinite(result))
{
    // ...
}

2
Зачем использовать Number.(POSITIVE|NEGATIVE)_INFINITYвместо -?Infinityили -?1/0?
Эли Грей

5
@Eli: Глобальное Infinityсвойство не предназначено только для чтения, что означает, что его можно переопределить: например, var x = 42; Infinity = 42; alert(x === Infinity);отображается «true» . (По общему признанию, это непонятный случай, и любой, кто решит InfinityNaN
изменить

Игнорируя тот факт, что Number.(POSITIVE|NEGATIVE)_INFINITYон не только для чтения , Infinity он также доступен только для чтения в строгом режиме. А как насчет -?1/0дела, которое я вам представил? В любом случае, вы должны почти всегда использовать isFiniteвместо него.
Эли Грей

1
@Eli: В моих тестах , Number.POSITIVE_INFINITYи Number.NEGATIVE_INFINITY которые только для чтения (проверено на Chrome8, FF3.6 и IE8). Использование 1/0работает нормально, но разработчикам вашего кода будет не так очевидно, что вы на самом деле пытаетесь проверить. Я согласен с тем, что использование isFinite- почти всегда лучший способ делать что-либо - поэтому я упомянул об этом в своем ответе - но только OP может решить, соответствует ли он их требованиям.
LukeH

4
Они не предназначены только для чтения (читай: не настраиваются ), это просто средства доступа с геттерами, но без сеттеров. Вы можете переопределить их с помощью Object.definePropertyи __defineGetter__. Infinity, С другой стороны, это не настраивается в строгом режиме.
Эли Грей

9

Простой n === n+1или n === n/0работает:

function isInfinite(n) {
  return n === n/0;
}

Имейте в виду, что родной isFinite()код приводит входные данные к числам. isFinite([])и isFinite(null)оба trueнапример.


Это совершенно неверный ответ. n === n+1оценивается как истина для всех чисел больше 2 ^ 53, т. е. 1e30. Разделение работает даже для NaN и -Infinity. Однако ответ LukeH дает вам более читаемый код.
tglas 04

@tglas Почему плюс такой? Рад, что разделение прочное. ИМО, мой код более читабелен и более инклюзивен, потому что математика более универсальна, чем слова.
ryanve

1
Поскольку 64-битные числа с плавающей запятой IEEE имеют 53 значащих двоичных цифры (см. En.wikipedia.org/wiki/IEEE_754 ), поэтому n+1не могут быть представлены и подлежат округлению. Что ж, даже целые числа подвержены ошибкам округления. Кстати, я не думаю, что ваш код "математически обоснован", просто попробуйте n === n/-0. При заполнении вещественных чисел с помощью +/- inf ваш предел не определен четко, если основная нулевая последовательность не предполагается положительной.
tglas

Спасибо @tglas, мне всегда нравится, что JavaScript может делиться на ноль :)
ryanve

6

В ES6, Number.isFinite()метод определяет, является ли переданное значение конечным числом.

Number.isFinite(Infinity);  // false
Number.isFinite(NaN);       // false
Number.isFinite(-Infinity); // false

Number.isFinite(0);         // true
Number.isFinite(2e64);      // true

Доступно из ECMAScript 1
MohaMad

2

На самом деле n === n + 1 будет работать для чисел больше 51 бит, например

1e16 + 1 === 1e16; // true
1e16 === Infinity; // false

3
Это должен быть комментарий к ответу Райанве.
Гэри

1

Мне нравится использовать Lodash по разным причинам, связанным с защитным кодированием, а также для удобства чтения. ES6 Number.isFiniteвеликолепен и не имеет проблем с нечисловыми значениями, но если ES6 невозможно, у вас уже есть lodash или вам нужен более короткий код: _.isFinite

_.isFinite(Infinity); // false
_.isFinite(NaN); // false
_.isFinite(-Infinity); // false

_.isFinite(null); // false
_.isFinite(3); // true
_.isFinite('3'); // true

0

Я столкнулся со сценарием, который требовал от меня проверки того, имеет ли значение тип NaNили, Infinityно передавать строки как допустимые результаты. Поскольку многие текстовые строки дают ложное срабатывание NaN, я сделал простое решение, чтобы обойти это:

  const testInput = input => input + "" === "NaN" || input + "" === "Infinity";

Приведенный выше код преобразует значения в строки и проверяет, равны ли они строго NaN или Infinity (вам нужно добавить еще один регистр для отрицательной бесконечности).

Так:

testInput(1/0); // true
testInput(parseInt("String")); // true
testInput("String"); // false

Этот пост на самом деле не имеет отношения к фактическому вопросу здесь и был бы лучше в качестве комментария под принятым ответом. OP - это числа и бесконечность, а не строки и NaNs и т. Д.
code_dredd

Вы, наверное, правы, @code_dredd - анекдот не имеет отношения к делу. Но решение по-прежнему работает: оно может определять бесконечное число - поправьте меня, если я ошибаюсь.
dmitrizzle 01

Это не относится к делу. Уже есть ответ, показывающий, как это сделать правильно . То, что у вас есть, «работает» просто потому, что сам язык делает глупые вещи и несовместим с тем, как он управляет типами. Пожалуйста, спасите себя от написания такого кода взлома.
code_dredd 01

Сделал бы вас счастливее, если бы я использовал toString()вместо этого? Не стесняйтесь голосовать против или указывать причины, по которым это может привести к противоречивым результатам или почему именно этот метод не рекомендуется. До сих пор я все еще чувствую, что это добавляет возможность для тех, кто ищет ответ, и нет никаких конкретных причин, почему это опасно, нестабильно и т. Д.
dmitrizzle

-1

Вы можете использовать isFinite в окне isFinite(123):

Вы можете написать такую ​​функцию, как:

function isInfinite(num) {
 return !isFinite(num);
}

И используйте как:

isInfinite(null); //false
isInfinite(1); //false
isInfinite(0); //false
isInfinite(0.00); //false
isInfinite(NaN); //true
isInfinite(-1.797693134862316E+308); //true
isInfinite(Infinity); //true
isInfinite(-Infinity); //true
isInfinite(+Infinity); //true
isInfinite(undefined); //true

Вы также можете Number.isFinite, который также проверяет, является ли значение также числом и более точным для проверки undefinedи nullт. Д.

Или вы можете полифилить его так:

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.