Bir sayının sonsuz olarak değerlendirilip değerlendirilmediğini nasıl kontrol ederim?


97

Kullanıcı tercihlerine bağlı olarak Infinity'yi gösteren (yalnızca IE altında) bir dizi Javascript hesaplamam var.

InfinityÖrneğin, kelimenin görünmesi nasıl durdurulur ve 0.0bunun yerine gösterilir?

Yanıtlar:


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

isFiniteNasıl tedavi etmek istediğinize bağlı olarak, muhtemelen bunun yerine işlevi kullanabilirsiniz NaN. numaranız , veya ise isFinitedöndürür .falsePOSITIVE_INFINITYNEGATIVE_INFINITYNaN

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

2
Neden Number.(POSITIVE|NEGATIVE)_INFINITYyerine -?Infinityya da kullanmalı -?1/0?
Eli Gray

5
@Eli: Global Infinityözellik salt okunur değildir, bu da yeniden tanımlanabileceği anlamına gelir: Örneğin, "true"var x = 42; Infinity = 42; alert(x === Infinity); görüntüler . (Kuşkusuz bilinmeyen bir durum olduğunu ve karar herkes yeniden tanımlama , vb garip şeyler olmaya beklemelidir.)InfinityNaN
LukeH

Gerçeğini göz ardı edilmesi Number.(POSITIVE|NEGATIVE)_INFINITYya salt okunur değil, Infinity olduğu salt okunur Katı modda. Ayrıca, -?1/0size sunduğum dava ne olacak? Her neyse, isFinitebunun yerine neredeyse her zaman kullanmalısınız .
Eli Gray

1
@Eli: Benim testlerde Number.POSITIVE_INFINITYve Number.NEGATIVE_INFINITY edilir salt okunur (Chrome8, FF3.6 ve IE8 üzerinde test). Kullanmak iyi 1/0çalışır, ancak kodunuzun bakımcıları için aslında neyi test etmeye çalıştığınız o kadar açık olmayacaktır. Kullanmanın isFiniteneredeyse her zaman bir şeyler yapmanın daha iyi bir yolu olduğuna katılıyorum - bu yüzden cevabımda bundan bahsetmiştim - ancak gereksinimlerini karşılayıp karşılamadığına sadece OP karar verebilir.
LukeH

4
Salt okunur değiller (okuma: yapılandırılamaz ), sadece alıcıları olan ancak ayarlayıcıları olmayan erişimcilerdir. Bunları Object.definePropertyve ile yeniden tanımlayabilirsiniz __defineGetter__. InfinityÖte yandan, bir katı modda olmayan yapılandırılabilir.
Eli Gray

9

Basit n === n+1veya n === n/0çalışır:

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

Bu yerli unutmayın isFinite()numaralara coerces girdiler. isFinite([])ve isFinite(null)her ikisi truede örneğin.


Bu cevap düpedüz yanlıştır. n === n+12 ^ 53'ten büyük tüm sayılar, yani 1e30 için doğru olarak değerlendirilir. Bölme kesmek, NaN ve -Infinity için bile çalışır. Bununla birlikte, LukeH'nin cevabı size waaaay'e daha okunaklı bir kod verir.
tglas

@tglas Artı neden böyle? Bölümün sağlam olmasına sevindim. IMO benim kodum daha okunabilir ve daha kapsayıcı çünkü matematik kelimelerden daha evrenseldir.
ryanve

1
IEEE 64bit kayan noktaların 53 önemli ikili basamağı olduğundan (bkz. En.wikipedia.org/wiki/IEEE_754 ), bu nedenle n+1temsil edilemez ve yuvarlamaya tabidir. Tam sayılar bile yuvarlama hatalarından etkilenir. Btw, kodunuzun "matematik kanıtı" olduğunu sanmıyorum, sadece deneyin n === n/-0. Gerçekleri +/- inf ile tamamlarken, altta yatan sıfır sekansının pozitif olduğu varsayılmadıkça limitiniz iyi tanımlanmamıştır.
tglas

Teşekkürler @tglas JavaScript'in sıfıra bölünebilmesini her zaman seveceğim :)
ryanve

7

In ES6, Number.isFinite()Yöntem, aktarılan değerin sonlu bir sayı olup olmadığını belirler.

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

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

ECMAScript 1'den erişilebilir
MohaMad

2

Aslında n === n + 1, 51 bitten büyük sayılar için çalışacaktır, ör.

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

3
Bu Ryanve'nin cevabına bir yorum olmalı.
Gary

1

Lodash'ı okunabilirliğin yanı sıra çeşitli savunma kodlama nedenleri için kullanmayı seviyorum . ES6 Number.isFiniteharika ve sayısal olmayan değerlerle ilgili sorunları yok, ancak ES6 mümkün değilse, zaten lodash'ınız var veya daha kısa kod istiyorsunuz: _.isFinite

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

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

0

Değerin NaNveya Infinitytüründe olup olmadığını kontrol etmemi, ancak dizeleri geçerli sonuçlar olarak iletmemi gerektiren bir senaryoyla karşılaştım . Birçok metin dizesi yanlış pozitif üreteceğinden NaN, bunu aşmak için basit bir çözüm buldum:

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

Yukarıdaki kod, değerleri dizelere dönüştürür ve bunların kesinlikle NaN veya Infinity'ye eşit olup olmadıklarını kontrol eder (negatif sonsuzluk için başka bir durum eklemeniz gerekir).

Yani:

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

Bu gönderi, buradaki asıl soruyla gerçekten ilgilenmiyor ve kabul edilen cevabın altında bir yorum olarak daha iyi olurdu. OP sayılar ve NaN
sonsuzla ilgilidir

Muhtemelen haklısın, @code_dredd - anekdot alakalı değil. Ancak çözüm hala işe yarıyor: sonsuz sayıyı algılayabilir - yanılıyorsam lütfen beni düzeltin.
dmitrizzle

Asıl konu bu değil. Gösterileri nasıl bunu yapmak pek bir cevap zaten var doğru . Sahip olduğunuz şey "işe yarıyor" çünkü dilin kendisi aptalca şeyler yapıyor ve türleri yönetme biçimiyle tutarsız. Lütfen kendinizi böyle bir hack kodu yazmaktan kurtarın.
code_dredd

Onun toString()yerine kullanırsam seni daha mutlu eder miydi? Bunun nasıl tutarsız sonuçlara yol açabileceğine veya tam olarak bu yöntemin neden önerilmediğine dair olumsuz oy vermekten veya bunun nedenlerini belirtmekten çekinmeyin. Şimdiye kadar, hala bir cevap arayanlar için bir seçenek eklediğini hissediyorum ve bunun tehlikeli, istikrarsız vb.
Olmasının

-1

İsFinite'ı pencerede kullanabilirsiniz ,isFinite(123) :

Şöyle bir fonksiyon yazabilirsiniz:

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

Ve şu şekilde kullanın:

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

Ayrıca Number.isFinitdeğerin de Sayı olup olmadığını ve kontrol için daha doğru olup olmadığını kontrol edebilir undefinedvenull vb ...

Veya şu şekilde çoklu doldurabilirsiniz :

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.