¿Cómo verifico si un número se evalúa como infinito?


94

Tengo una serie de cálculos de Javascript que (solo en IE) muestran Infinity dependiendo de las opciones del usuario.

¿Cómo se detiene la Infinityaparición de la palabra y, por ejemplo, se muestra en su 0.0lugar?

Respuestas:


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

En su lugar, podría usar la isFinitefunción, dependiendo de cómo quiera tratar NaN. isFinitedevuelve falsesi su número es POSITIVE_INFINITY, NEGATIVE_INFINITYo NaN.

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

2
¿Por qué usar en Number.(POSITIVE|NEGATIVE)_INFINITYlugar de -?Infinityo -?1/0?
Eli Gray

5
@Eli: la Infinitypropiedad global no es de solo lectura, lo que significa que se puede redefinir: por ejemplo, var x = 42; Infinity = 42; alert(x === Infinity);muestra "verdadero" . (Es cierto que ese es un caso oscuro, y cualquiera que decida redefinir Infinity, NaNetc. debe esperar que sucedan cosas extrañas).
LukeH

Ignorando el hecho de que Number.(POSITIVE|NEGATIVE)_INFINITYtampoco es de solo lectura , Infinity es de solo lectura en modo estricto. Además, ¿qué pasa con el -?1/0caso que les presenté? De todos modos, casi siempre deberías usar isFiniteen su lugar.
Eli Gray

1
@Eli: En mis pruebas Number.POSITIVE_INFINITYy Number.NEGATIVE_INFINITY son de solo lectura (probados en Chrome8, FF3.6 e IE8). El uso 1/0funciona bien, pero no será tan obvio para quienes mantienen su código lo que realmente está tratando de probar. Estoy de acuerdo en que usar isFinitees casi siempre la mejor manera de hacer las cosas, por eso lo mencioné en mi respuesta, pero solo el OP puede decidir si cumple con sus requisitos.
LukeH

4
No son de solo lectura (lectura: no configurables ), son solo accesos con captadores pero sin definidores. Puede redefinirlos con Object.definePropertyy __defineGetter__. Infinity, por otro lado, no es configurable en modo estricto.
Eli Gray

9

Un simple n === n+1o n === n/0funciona:

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

Tenga en cuenta que el nativo isFinite()coacciona las entradas a los números. isFinite([])y isFinite(null)son ambos, truepor ejemplo.


Esta respuesta es completamente incorrecta. n === n+1se evalúa como verdadero para todos los números mayores que 2 ^ 53, es decir, 1e30. El truco de división funciona, incluso para NaN e -Infinity. Sin embargo, la respuesta de LukeH le brinda un código mucho más legible.
tglas

@tglas ¿Por qué el plus es así? Me alegro de que la división sea sólida. En mi opinión, mi código es más legible y más inclusivo porque las matemáticas son más universales que las palabras.
Ryanve

1
Debido a que los flotantes IEEE de 64 bits tienen 53 dígitos binarios significativos (consulte en.wikipedia.org/wiki/IEEE_754 ), n+1no se pueden representar y están sujetos a redondeo. Bueno, incluso los números enteros se ven afectados por los errores de redondeo. Por cierto, no creo que tu código sea "a prueba de matemáticas", solo inténtalo n === n/-0. Al completar los reales con +/- inf, su límite no está bien definido a menos que se asuma que la secuencia cero subyacente es positiva.
tglas

Gracias @tglas Siempre me encantará que JavaScript pueda dividir por cero :)
ryanve

6

En ES6, El Number.isFinite()método determina si el valor pasado es un número finito.

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

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

Accesible desde ECMAScript 1
MohaMad

2

En realidad, n === n + 1 funcionará para números mayores de 51 bits, por ejemplo

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

3
Este debería ser un comentario sobre la respuesta de Ryanve.
Gary

1

Me gusta usar Lodash por una variedad de razones de codificación defensiva , así como por la legibilidad. ES6 Number.isFinitees excelente y no tiene problemas con valores no numéricos, pero si ES6 no es posible, ya tiene lodash o desea un código más breve: _.isFinite

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

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

0

Me encontré con un escenario que me obligaba a verificar si el valor es del tipo NaNo, Infinitypero pasar cadenas como resultados válidos. Debido a que muchas cadenas de texto producirán falsos positivos NaN, he creado una solución simple para eludir eso:

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

El código anterior convierte los valores en cadenas y comprueba si son estrictamente iguales a NaN o Infinity (deberá agregar otro caso para el infinito negativo).

Entonces:

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

Esta publicación realmente no trata la pregunta real aquí y hubiera sido mejor como comentario debajo de la respuesta aceptada. El OP trata sobre números e infinito, no cadenas y NaNs, etc.
code_dredd

Probablemente tengas razón, @code_dredd: la anécdota no es relevante. Pero la solución sigue funcionando: puede detectar el número infinito; corríjame si me equivoco.
dmitrizzle

Eso no viene al caso. Ya existe una respuesta que muestra cómo hacer esto correctamente . Lo que tienes "funciona" simplemente porque el lenguaje en sí hace cosas tontas y es inconsistente con la forma en que maneja los tipos. Por favor, ahórrese de escribir código de pirateo como este.
code_dredd

¿Te haría más feliz si usara en su toString()lugar? Siéntase libre de votar en contra o indicar las razones por las que esto podría producir resultados inconsistentes o por qué no se recomienda exactamente este método. Hasta el momento, todavía siento que añade una opción para quien sea que esté buscando una respuesta y no hay ninguna razón concretas por las que esto es peligroso, inestable, etc.
dmitrizzle

-1

Puede usar isFinite en la ventana isFinite(123):

Puedes escribir una función como:

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

Y usa como:

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

También puede Number.isFinitE, que también comprobar si el valor es un número demasiado y es más preciso para la comprobación undefinedy nulletc ...

O puede rellenarlo así:

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.