Як перевірити, чи число оцінюється до нескінченності?


94

У мене є низка обчислень Javascript, які (лише в IE) показують нескінченність залежно від вибору користувача.

Як зупинити Infinityпояву слова і, наприклад, показати 0.0натомість?

Відповіді:


174
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" . (Треба визнати , що це маловідомий випадок, і будь-який , хто вирішить переглянути Infinity, і NaNт.д. слід очікувати дивні речі траплятися.)
LukeH

Ігноруючи той факт, що Number.(POSITIVE|NEGATIVE)_INFINITYтакож не лише для читання , Infinity це лише для читання в суворому режимі. Крім того, як щодо -?1/0справи, яку я вам представив? У будь-якому випадку, isFiniteзамість цього слід майже завжди використовувати .
Eli Gray

1
@Eli: У моїх тестах Number.POSITIVE_INFINITYі Number.NEGATIVE_INFINITY лише для читання (протестовано на Chrome8, FF3.6 та IE8). Використання 1/0працює нормально, але для розробників вашого коду це не буде настільки очевидним, на що ви насправді намагаєтеся перевірити. Я погоджуюсь, що використання isFiniteмайже завжди є кращим способом зробити щось - саме тому я згадав про це у своїй відповіді - але лише ОП може вирішити, чи відповідає воно їхнім вимогам.
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

@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
Це має бути коментар до відповіді ryanve.
Gary

1

Я люблю використовувати Lodash з різних причин захисного кодування , а також для читабельності. ES6 Number.isFiniteчудовий і не має проблем із нечисловими значеннями, але якщо ES6 неможливий, ви вже маєте лодаш або хочете коротший код: _.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

У цьому справа не в тому. Уже є відповідь, яка показує, як це правильно робити . Те, що у вас "працює", просто тому, що сама мова робить безглузді речі і не узгоджується з тим, як вона управляє типами. Будь ласка, позбавте себе від написання такого коду злому.
code_dredd

Чи було б ви щасливішими, якби я використовував 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.