Bagaimana cara memeriksa apakah suatu angka bernilai hingga tak terbatas?


94

Saya memiliki serangkaian perhitungan Javascript yang (hanya di bawah IE) menunjukkan Infinity tergantung pada pilihan pengguna.

Bagaimana cara seseorang menghentikan Infinitykemunculan kata dan misalnya, muncul 0.0?

Jawaban:


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

Anda mungkin bisa menggunakan isFinitefungsi tersebut, tergantung bagaimana Anda ingin memperlakukannya NaN. isFinitekembali falsejika nomor Anda POSITIVE_INFINITY, NEGATIVE_INFINITYatau NaN.

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

2
Mengapa menggunakan Number.(POSITIVE|NEGATIVE)_INFINITYalih-alih -?Infinityatau -?1/0?
Eli Grey

5
@Eli: InfinityProperti global bukan hanya-baca yang berarti dapat didefinisikan ulang: Misalnya, var x = 42; Infinity = 42; alert(x === Infinity);menampilkan "benar" . (Memang itu kasus yang tidak jelas, dan siapa pun yang memutuskan untuk mendefinisikan ulang Infinity, NaNdll harus mengharapkan hal-hal aneh terjadi.)
LukeH

Mengabaikan fakta yang Number.(POSITIVE|NEGATIVE)_INFINITYjuga bukan hanya-baca, Infinity adalah hanya-baca dalam mode ketat. Juga, bagaimana dengan -?1/0kasus yang saya perlihatkan kepada Anda? Bagaimanapun, Anda hampir selalu harus menggunakan isFinite.
Eli Grey

1
@Eli: Dalam tes saya Number.POSITIVE_INFINITYdan Number.NEGATIVE_INFINITY yang read-only (diuji pada Chrome8, FF3.6 dan IE8). Menggunakan 1/0berfungsi dengan baik tetapi tidak akan terlalu jelas bagi pengelola kode Anda apa yang sebenarnya Anda coba uji. Saya setuju bahwa menggunakan isFinitehampir selalu merupakan cara yang lebih baik untuk melakukan sesuatu - itulah mengapa saya menyebutkannya dalam jawaban saya - tetapi hanya OP yang dapat memutuskan apakah itu memenuhi persyaratan mereka.
LukeH

4
Mereka tidak hanya-baca (baca: tidak dapat dikonfigurasi ), mereka hanya aksesor dengan pengambil tetapi tidak ada penyetel. Anda dapat mendefinisikannya kembali dengan Object.definePropertydan __defineGetter__. Infinity, Di sisi lain, adalah non-dikonfigurasi dalam mode ketat.
Eli Gray

9

Sederhana n === n+1atau n === n/0bekerja:

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

Ketahuilah bahwa native isFinite()memaksa input ke angka. isFinite([])dan isFinite(null)keduanya truesebagai contoh.


Jawaban ini salah. n === n+1mengevaluasi ke true untuk semua bilangan yang lebih besar dari 2 ^ 53, yaitu, 1e30. Peretasan divisi berfungsi, bahkan untuk NaN dan -Infinity. Namun, jawaban LukeH memberi Anda kode yang lebih mudah dibaca.
tglas

@tglas Mengapa plus seperti itu? Senang pembagiannya solid. IMO kode saya lebih mudah dibaca dan lebih inklusif karena matematika lebih universal daripada kata-kata.
ryanve

1
Karena float IEEE 64bit memiliki 53 digit biner yang signifikan (lihat en.wikipedia.org/wiki/IEEE_754 ), jadi n+1tidak dapat direpresentasikan dan dapat dibulatkan. Nah, bahkan bilangan bulat dipengaruhi oleh kesalahan pembulatan. Ngomong-ngomong, menurut saya kode Anda tidak "tahan matematika", coba saja n === n/-0. Saat melengkapi real dengan +/- inf, batas Anda tidak terdefinisi dengan baik kecuali urutan nol yang mendasarinya diasumsikan positif.
tglas

Terima kasih @tglas Saya akan selalu menyukai JavaScript yang dapat dibagi dengan nol :)
ryanve

6

Di ES6, Number.isFinite()Metode menentukan apakah nilai yang diteruskan adalah bilangan terbatas.

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

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

Dapat diakses dari ECMAScript 1
MohaMad

2

Sebenarnya n === n + 1 akan bekerja untuk angka yang lebih besar dari 51 bit, misalnya

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

3
Ini harus menjadi komentar atas jawaban ryanve.
Gary

1

Saya suka menggunakan Lodash untuk berbagai alasan pengkodean pertahanan serta keterbacaan. ES6 Number.isFinitebagus dan tidak memiliki masalah dengan nilai non-numerik, tetapi jika ES6 tidak memungkinkan, Anda sudah memiliki lodash, atau menginginkan kode yang lebih singkat: _.isFinite

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

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

0

Saya telah mengalami skenario yang mengharuskan saya untuk memeriksa apakah nilainya dari tipe NaNatau Infinitytetapi meneruskan string sebagai hasil yang valid. Karena banyak string teks akan menghasilkan positif palsu NaN, saya telah membuat solusi sederhana untuk mengelak itu:

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

Kode di atas mengubah nilai menjadi string dan memeriksa apakah nilainya benar-benar sama dengan NaN atau Infinity (Anda harus menambahkan case lain untuk infinity negatif).

Begitu:

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

Posting ini tidak benar-benar menangani pertanyaan sebenarnya di sini dan akan lebih baik sebagai komentar di bawah jawaban yang diterima. OP adalah tentang angka dan infinity, bukan string dan NaNs, dll.
code_dredd

Anda mungkin benar, @code_dredd - anekdot tidak relevan. Tetapi solusinya masih berfungsi: ia dapat mendeteksi angka tak terhingga - tolong perbaiki saya jika saya salah.
dmitrizzle

Itu tidak penting. Sudah ada jawaban yang menunjukkan bagaimana melakukan ini dengan benar . Apa yang Anda miliki "berhasil" hanya karena bahasanya sendiri melakukan hal-hal konyol dan tidak konsisten dengan cara mengelola jenis. Tolong selamatkan diri Anda dari menulis kode hack seperti ini.
code_dredd

Apakah itu akan membuat Anda lebih bahagia jika saya menggunakannya toString()? Jangan ragu untuk memberi suara negatif atau menyatakan alasan bagaimana hal ini dapat memberikan hasil yang tidak konsisten atau mengapa metode ini tidak disarankan. Sejauh ini, saya masih merasa ini menambahkan opsi bagi siapa pun yang mencari jawaban dan tidak ada alasan konkret mengapa ini berbahaya, tidak stabil, dll.
dmitrizzle

-1

Anda dapat menggunakan isFinite di jendela, isFinite(123):

Anda dapat menulis fungsi seperti:

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

Dan gunakan seperti:

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

Anda juga dapat Number.isFinite yang juga memeriksa apakah nilainya juga Angka dan lebih akurat untuk memeriksa undefineddan nulllain - lain ...

Atau Anda dapat mengisinya seperti ini:

Number.isFinite = Number.isFinite || function(value) {
  return typeof value === 'number' && isFinite(value);
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.