Jawaban:
Anda masih bisa mendapatkan nilai bukan angka (NaN) dari aritmatika sederhana yang melibatkan inf
:
>>> 0 * float("inf")
nan
Perhatikan bahwa Anda biasanya tidak akan mendapatkan inf
nilai melalui perhitungan aritmatika biasa:
>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')
The inf
nilai dianggap sebagai nilai yang sangat khusus dengan semantik yang tidak biasa, jadi lebih baik untuk mengetahui tentang OverflowError
langsung melalui pengecualian, daripada memiliki inf
nilai diam-diam disuntikkan ke dalam perhitungan Anda.
**
tampak agak buggy. Ketika meluap dengan angka nyata, ia melempar kesalahan, tetapi ketika salah satu operandnya adalah inf
atau -inf
, ia mengembalikan salah satu 0.0
atau inf
. Jadi tidak bekerja dengan benar ketika input inifinty, tetapi tidak ketika hasilnya harus tak terhingga.
Implementasi Python mengikuti standar IEEE-754 dengan cukup baik, yang dapat Anda gunakan sebagai panduan, tetapi ia bergantung pada sistem yang mendasari kompilasi, sehingga perbedaan platform dapat terjadi. Baru-baru ini¹, perbaikan telah diterapkan yang memungkinkan "infinity" serta "inf" , tetapi itu tidak penting di sini.
Bagian berikut ini sama-sama berlaku untuk bahasa apa pun yang menerapkan aritmatika titik apung IEEE dengan benar, tidak khusus hanya untuk Python.
Ketika berhadapan dengan operator tanpa batas dan operator lebih besar daripada >
atau lebih kecil <
, berikut ini diperhitungkan:
+inf
lebih tinggi dari-inf
-inf
lebih rendah dari+inf
+inf
yang tidak lebih tinggi atau lebih rendah dari+inf
-inf
tidak lebih tinggi atau lebih rendah dari -inf
NaN
salah ( inf
tidak lebih tinggi, atau lebih rendah dari NaN
)Jika dibandingkan untuk kesetaraan, +inf
dan +inf
sama, seperti apa adanya -inf
dan -inf
. Ini adalah masalah yang banyak diperdebatkan dan mungkin terdengar kontroversial bagi Anda, tetapi itu dalam standar IEEE dan Python berperilaku seperti itu.
Tentu saja, +inf
tidak sama dengan -inf
dan segala sesuatu, termasuk NaN
dirinya sendiri, tidak sama dengan NaN
.
Sebagian besar perhitungan dengan tak terhingga akan menghasilkan tak terhingga, kecuali kedua operan adalah tak terhingga, ketika divisi operasi atau modulo, atau dengan perkalian dengan nol, ada beberapa aturan khusus yang perlu diingat:
NaN
0.0
atau -0.0
².NaN
.inf - inf
, hasilnya tidak terdefinisi: NaN
;inf - -inf
, hasilnya adalah inf
;-inf - inf
, hasilnya adalah -inf
;-inf - -inf
, hasilnya tidak terdefinisi: NaN
.inf + inf
, hasilnya adalah inf
;inf + -inf
, hasilnya tidak terdefinisi: NaN
;-inf + inf
, hasilnya tidak terdefinisi: NaN
;-inf + -inf
, hasilnya adalah -inf
.math.pow
, pow
atau **
rumit, karena tidak berperilaku sebagaimana mestinya. Itu melempar pengecualian melimpah ketika hasil dengan dua bilangan real terlalu tinggi untuk muat pelampung presisi ganda (harus mengembalikan tak terhingga), tetapi ketika inputnya inf
atau -inf
, itu berperilaku benar dan mengembalikan salah satu inf
atau 0.0
. Ketika argumen kedua adalah NaN
, ia kembali NaN
, kecuali argumen pertama adalah 1.0
. Ada lebih banyak masalah, tidak semua dibahas dalam dokumen .math.exp
menderita masalah yang sama dengan math.pow
. Solusi untuk memperbaiki ini untuk overflow adalah dengan menggunakan kode yang mirip dengan ini:
try:
res = math.exp(420000)
except OverflowError:
res = float('inf')
Catatan 1: sebagai peringatan tambahan, yang seperti yang didefinisikan oleh standar IEEE, jika hasil perhitungan Anda di bawah atau melebihi, hasilnya tidak akan menjadi kesalahan di bawah atau overflow, tetapi tak terhingga positif atau negatif: 1e308 * 10.0
hasil inf
.
Catatan 2: karena kalkulasi apa pun dengan NaN
pengembalian NaN
dan perbandingan apa pun dengan NaN
, termasuk NaN
dirinya sendiri false
, Anda harus menggunakan math.isnan
fungsi ini untuk menentukan apakah suatu angka memang benar NaN
.
Catatan 3: meskipun Python mendukung penulisan float('-NaN')
, tanda diabaikan, karena tidak ada tanda pada NaN
internal. Jika Anda membagi -inf / +inf
, hasilnya adalah NaN
tidak -NaN
(tidak ada hal seperti itu).
Catatan 4: berhati-hatilah untuk mengandalkan salah satu di atas, karena Python bergantung pada C atau Java library yang dikompilasi untuk dan tidak semua sistem yang mendasarinya menerapkan semua perilaku ini dengan benar. Jika Anda ingin memastikan, uji untuk tak terbatas sebelum melakukan perhitungan Anda.
¹) Baru-baru ini berarti sejak versi 3.2 .
²) Floating point mendukung nol positif dan negatif, jadi: x / float('inf')
pertahankan tanda dan -1 / float('inf')
hasil -0.0
, 1 / float(-inf)
hasil -0.0
, 1 / float('inf')
hasil 0.0
dan -1/ float(-inf)
hasil 0.0
. Selain itu, 0.0 == -0.0
adalahtrue
, Anda harus memeriksa secara manual tanda jika Anda tidak ingin menjadi benar.
-1 * float('infinity') == -inf
Begitu juga C99 .
Representasi floating point IEEE 754 yang digunakan oleh semua prosesor modern memiliki beberapa pola bit khusus yang dicadangkan untuk infinity positif (tanda = 0, exp = ~ 0, frac = 0), infinity negatif (tanda = 1, exp = ~ 0, frac = 0 ), dan banyak NaN (Bukan Angka: exp = ~ 0, frac ≠ 0).
Yang perlu Anda khawatirkan: beberapa aritmatika dapat menyebabkan pengecualian / perangkap titik mengambang, tetapi itu tidak terbatas hanya pada konstanta "menarik" ini.
OverflowError
.
Saya menemukan peringatan yang sejauh ini tidak ada yang disebutkan. Saya tidak tahu apakah itu akan sering muncul dalam situasi praktis, tetapi ini demi kelengkapan.
Biasanya, menghitung angka tak terbatas modulo mengembalikan dirinya sebagai pelampung, tetapi sebagian kecil tak terbatas modulo kembali nan
(bukan angka). Berikut ini sebuah contoh:
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
Saya mengajukan masalah pada pelacak bug Python. Itu dapat dilihat di https://bugs.python.org/issue32968 .
Pembaruan: ini akan diperbaiki dalam Python 3.8 .
CAVEAT SANGAT BURUK: Divisi dengan Nol
dalam 1/x
sepersekian, sampai saat x = 1e-323
itu inf
tetapi ketika x = 1e-324
atau sedikit itu melemparZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
jadi berhati-hatilah!
1e309
akan ditafsirkan sebagai+inf
dan-1e309
akan ditafsirkan sebagai-inf
.