Jak sprawdzić, czy liczba przyjmuje nieskończoność?


95

Mam szereg obliczeń Javascript, które (tylko w IE) pokazują Infinity w zależności od wyborów użytkownika.

Jak zatrzymać Infinitypojawianie się słowa i na przykład pokazać 0.0zamiast niego?

Odpowiedzi:


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

Możesz isFinitezamiast tego użyć tej funkcji, w zależności od tego, jak chcesz leczyć NaN. isFinitezwraca, falsejeśli Twój numer to POSITIVE_INFINITY, NEGATIVE_INFINITYlub NaN.

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

2
Dlaczego warto używać Number.(POSITIVE|NEGATIVE)_INFINITYzamiast -?Infinitylub -?1/0?
Eli Gray,

5
@Eli: Infinitywłaściwość global nie jest tylko do odczytu, co oznacza, że ​​można ją przedefiniować: na przykład var x = 42; Infinity = 42; alert(x === Infinity);wyświetla wartość „true” . (Trzeba przyznać, że to niejasny przypadek i każdy, kto zdecyduje się na przedefiniowanie Infinity, NaNitp., Powinien spodziewać się dziwnych rzeczy.)
LukeH

Ignorowanie faktu, że również Number.(POSITIVE|NEGATIVE)_INFINITYnie jest tylko do odczytu , Infinity jest tylko do odczytu w trybie ścisłym. A co z -?1/0przypadkiem, który ci przedstawiłem? W każdym razie prawie zawsze powinieneś używać isFinitezamiast tego.
Eli Grey

1
@Eli: W moich testach Number.POSITIVE_INFINITYi Number.NEGATIVE_INFINITY tylko do odczytu (testowane na Chrome8, FF3.6 i IE8). Używanie 1/0działa dobrze, ale dla opiekunów Twojego kodu nie będzie to takie oczywiste, do czego faktycznie próbujesz testować. Zgadzam się, że używanie isFinitejest prawie zawsze lepszym sposobem robienia rzeczy - dlatego wspomniałem o tym w mojej odpowiedzi - ale tylko PO może zdecydować, czy spełnia jego wymagania.
LukeH

4
Nie są one tylko do odczytu (czytaj: nie można ich konfigurować ), są tylko akcesoriami z pobierającymi, ale bez ustawiania. Możesz je przedefiniować za pomocą Object.definePropertyi __defineGetter__. InfinityZ drugiej strony, jest non-konfigurowane w trybie ścisłym.
Eli Gray,

9

Prosty n === n+1lub n === n/0działa:

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

Należy pamiętać, że natywny isFinite()przekształca dane wejściowe do liczb. isFinite([])i isFinite(null)oba są truena przykład.


Ta odpowiedź jest po prostu błędna. n === n+1zwraca wartość true dla wszystkich liczb większych niż 2 ^ 53, tj. 1e30. Podział działa, nawet dla NaN i -Infinity. Jednak odpowiedź LukeHa daje bardzo czytelny kod.
tglas

@tglas Dlaczego ten plus jest taki? Cieszę się, że podział jest solidny. IMO mój kod jest bardziej czytelny i bardziej wszechstronny, ponieważ matematyka jest bardziej uniwersalna niż słowa.
ryanve

1
Ponieważ 64-bitowe liczby zmiennoprzecinkowe IEEE mają 53 znaczące cyfry binarne (patrz en.wikipedia.org/wiki/IEEE_754 ), n+1nie mogą być reprezentowane i podlegają zaokrąglaniu. Cóż, nawet liczby całkowite podlegają błędom zaokrągleń. Przy okazji, nie sądzę, żeby twój kod był "matematyczny", po prostu spróbuj n === n/-0. Podczas uzupełniania liczb rzeczywistych z +/- inf, twój limit nie jest dobrze zdefiniowany, chyba że zakłada się, że podstawowa sekwencja zerowa jest dodatnia.
tglas

Dzięki @tglas Zawsze będę zachwycony tym, że JavaScript może dzielić przez zero :)
ryanve

6

W ES6, Number.isFinite()Metoda określa, czy przekazana wartość jest liczbą skończoną.

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

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

Dostępne z ECMAScript 1
MohaMad

2

W rzeczywistości n === n + 1 będzie działać dla liczb większych niż 51 bitów, np

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

3
To powinien być komentarz do odpowiedzi Ryanve.
Gary,

1

Lubię używać Lodash z różnych powodów związanych z obroną kodowania, a także z powodu czytelności. ES6 Number.isFinitejest świetny i nie ma problemów z wartościami nienumerycznymi, ale jeśli ES6 nie jest możliwy, masz już lodash lub chcesz krótszy kod: _.isFinite

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

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

0

Wpadłem na scenariusz, który wymagał ode mnie sprawdzenia, czy wartość jest typu NaNlub, Infinityale przekazanie ciągów znaków jako prawidłowe wyniki. Ponieważ wiele ciągów tekstowych daje wynik fałszywie dodatni NaN, opracowałem proste rozwiązanie, aby obejść ten problem:

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

Powyższy kod konwertuje wartości na łańcuchy i sprawdza, czy są one ściśle równe NaN lub Nieskończoność (musisz dodać kolejny przypadek dla ujemnej nieskończoności).

Więc:

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

Ten post tak naprawdę nie dotyczy rzeczywistego pytania i byłby lepszy jako komentarz pod zaakceptowaną odpowiedzią. OP dotyczy liczb i nieskończoności, a nie łańcuchów i NaNs itp.
code_dredd

Prawdopodobnie masz rację, @code_dredd - anegdota nie ma znaczenia. Ale rozwiązanie nadal działa: może wykryć liczbę nieskończoną - popraw mnie, jeśli się mylę.
dmitrizzle

Nie w tym rzecz. Jest już odpowiedź, która pokazuje, jak to zrobić poprawnie . To, co masz, „działa” po prostu dlatego, że sam język robi głupie rzeczy i jest niezgodny z tym, jak zarządza typami. Proszę, uchroń się przed pisaniem takiego kodu hakerskiego.
code_dredd

Czy byłbyś szczęśliwszy, gdybym toString()zamiast tego użył ? Możesz głosować przeciw lub podać powody, dla których może to przynieść niespójne wyniki lub dlaczego dokładnie ta metoda nie jest zalecana. Jak dotąd nadal czuję, że dodaje opcję dla każdego, kto szuka odpowiedzi i nie ma żadnych konkretnych powodów, dla których jest to niebezpieczne, niestabilne itp.
dmitrizzle

-1

Możesz użyć isFinite w oknie isFinite(123):

Możesz napisać funkcję taką jak:

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

I używaj jak:

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

Można również Number.isFinitE, która również sprawdzić, czy wartość jest zbyt Number i jest bardziej dokładna dla sprawdzenia undefinedi nulletc ...

Lub możesz wypełnić go w następujący sposób:

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.