Wie überprüfe ich, ob eine Zahl unendlich ist?


93

Ich habe eine Reihe von Javascript-Berechnungen, die (nur unter IE) je nach Benutzerauswahl Infinity anzeigen.

Wie stoppt man das InfinityErscheinen des Wortes und zeigt es 0.0stattdessen?

Antworten:


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

Sie können die isFiniteFunktion möglicherweise stattdessen verwenden, je nachdem, wie Sie sie behandeln möchten NaN. isFinitezurück , falsewenn Ihre Zahl ist POSITIVE_INFINITY, NEGATIVE_INFINITYoder NaN.

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

2
Warum Number.(POSITIVE|NEGATIVE)_INFINITYanstelle von -?Infinityoder verwenden -?1/0?
Eli Gray

5
@Eli: Die globale InfinityEigenschaft nicht schreibgeschützt , was bedeutet , dass sie neu definiert werden kann: Zum Beispiel var x = 42; Infinity = 42; alert(x === Infinity);zeigt „true“ . (Zugegeben, das ist ein dunkler Fall, und jeder, der sich für eine Neudefinition usw. entscheidet Infinity, NaNsollte damit rechnen , dass seltsame Dinge passieren.)
LukeH

Das Ignorieren der Tatsache, dass Number.(POSITIVE|NEGATIVE)_INFINITYes auch nicht schreibgeschützt Infinity ist , ist im strengen Modus schreibgeschützt. Und was ist mit dem -?1/0Fall, den ich Ihnen vorgestellt habe? Wie auch immer, Sie sollten fast immer isFinitestattdessen verwenden.
Eli Gray

1
@Eli: In meinen Tests Number.POSITIVE_INFINITYund Number.NEGATIVE_INFINITY sind schreibgeschützt (getestet auf Chrome8, FF3.6 und IE8). Die Verwendung 1/0funktioniert einwandfrei, aber für die Betreuer Ihres Codes ist es nicht so offensichtlich, worauf Sie tatsächlich testen möchten. Ich stimme zu, dass die Verwendung isFinitefast immer der bessere Weg ist, Dinge zu tun - deshalb habe ich sie in meiner Antwort erwähnt -, aber nur das OP kann entscheiden, ob es ihren Anforderungen entspricht.
LukeH

4
Sie sind nicht schreibgeschützt (lesbar: nicht konfigurierbar ), sondern nur Accessoren mit Gettern, aber ohne Setter. Sie können sie mit Object.definePropertyund neu definieren __defineGetter__. InfinityAndererseits ist es im strengen Modus nicht konfigurierbar.
Eli Gray

9

Ein einfaches n === n+1oder n === n/0funktioniert:

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

isFinite()Beachten Sie, dass der Native Eingaben in Zahlen erzwingt. isFinite([])und isFinite(null)sind beide truezum Beispiel.


Diese Antwort ist einfach falsch. n === n+1wird für alle Zahlen größer als 2 ^ 53, dh 1e30, als wahr ausgewertet. Der Divisions-Hack funktioniert auch für NaN und -Infinity. Die Antwort von LukeH gibt Ihnen jedoch einen besser lesbaren Code.
tglas

@tglas Warum ist das Plus so? Ich bin froh, dass die Teilung solide ist. IMO mein Code ist lesbarer und umfassender, weil Mathematik universeller ist als Wörter.
Ryanve

1
Da IEEE 64-Bit-Floats 53 signifikante Binärziffern haben (siehe en.wikipedia.org/wiki/IEEE_754 ), n+1können sie nicht dargestellt werden und unterliegen einer Rundung. Nun, auch ganze Zahlen sind von Rundungsfehlern betroffen. Übrigens glaube ich nicht, dass Ihr Code "mathematisch" ist, versuchen Sie es einfachn === n/-0 . Wenn Sie die Reals mit +/- inf abschließen, ist Ihr Limit nicht genau definiert, es sei denn, die zugrunde liegende Nullsequenz wird als positiv angenommen.
Glas

Danke @tglas Ich werde es immer lieben, dass JavaScript durch Null teilen kann :)
Ryanve

6

In ES6, der Number.isFinite()bestimmt , ob die Methode übergebenen Wert eine endliche Zahl ist.

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

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

Erreichbar von ECMAScript 1
Mohamad

2

Tatsächlich funktioniert n === n + 1 für Zahlen größer als 51 Bit, z

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

3
Dies sollte ein Kommentar zu Ryanves Antwort sein.
Gary

1

Ich benutze Lodash aus verschiedenen Gründen der defensiven Codierung sowie aus Gründen der Lesbarkeit. ES6 Number.isFiniteist großartig und hat keine Probleme mit nicht numerischen Werten. Wenn ES6 jedoch nicht möglich ist, haben Sie bereits lodash oder möchten einen kürzeren Code: _.isFinite

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

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

0

Ich bin auf ein Szenario gestoßen, in dem ich überprüfen musste, ob der Wert vom Typ NaNoder ist, Infinityaber Zeichenfolgen als gültige Ergebnisse übergeben habe. Da viele Textzeichenfolgen falsch positiv sind NaN, habe ich eine einfache Lösung gefunden, um Folgendes zu umgehen:

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

Der obige Code konvertiert Werte in Zeichenfolgen und prüft, ob sie streng gleich NaN oder Infinity sind (Sie müssen einen weiteren Fall für negative Unendlichkeit hinzufügen).

So:

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

Dieser Beitrag befasst sich nicht wirklich mit der eigentlichen Frage hier und wäre als Kommentar unter der akzeptierten Antwort besser gewesen. Das OP handelt von Zahlen und Unendlichkeit, nicht von Zeichenfolgen und NaNs usw.
code_dredd

Sie haben wahrscheinlich Recht, @code_dredd - die Anekdote ist nicht relevant. Aber die Lösung funktioniert immer noch: Sie kann die Unendlichkeitszahl erkennen - bitte korrigieren Sie mich, wenn ich falsch liege.
Dmitrizzle

Das ist nebensächlich. Es gibt bereits eine Antwort, die zeigt, wie man das richtig macht . Was Sie haben, "funktioniert" einfach, weil die Sprache selbst alberne Dinge tut und nicht mit der Art und Weise übereinstimmt, wie sie Typen verwaltet. Bitte ersparen Sie sich das Schreiben eines solchen Hack-Codes.
code_dredd

Würde es dich glücklicher machen, wenn ich toString()stattdessen verwenden würde? Sie können gerne Gründe herabstimmen oder angeben, wie dies zu inkonsistenten Ergebnissen führen kann oder warum genau diese Methode nicht empfohlen wird. Bisher habe ich immer noch das Gefühl, dass es eine Option für jeden bietet, der nach einer Antwort sucht, und es gibt keine konkreten Gründe, warum dies gefährlich, instabil usw. ist
dmitrizzle

-1

Sie können isFinite im Fenster verwenden.isFinite(123) :

Sie können eine Funktion schreiben wie:

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

Und verwenden Sie wie:

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

Sie können auch Number.isFinitüberprüfen, ob der Wert auch Number ist und genauer für die Überprüfung von undefinedundnull etc ...

Oder Sie können polyfill es wie :

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.