Yanıtlar:
Basit aritmetik işlemlerden sayı olmayan (NaN) değerleri almaya devam edebilirsiniz inf:
>>> 0 * float("inf")
nan
Normalde normal aritmetik hesaplamalar yoluyla bir değer elde edemeyeceğinizi unutmayın inf:
>>> 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')
infBir hakkında bilmek daha iyidir, böylece değeri, alışılmadık semantik ile çok özel bir değer olarak kabul edilir OverflowErrorziyade bir olmasındansa hemen bir istisna yoluyla infsessizce hesaplamalar enjekte değeri.
**biraz arabası gibi görünüyor. Gerçek sayılarla taştığında, bir hata atar, ancak işlenenlerinden herhangi biri infya da olduğunda -inf, ya 0.0da döndürür inf. O yüzden yapar doğru işi girişi Inifinty olduğunda, ancak sonuç sonsuzluk olmalıdır değilken.
Python'un uygulaması , rehber olarak kullanabileceğiniz IEEE-754 standardını oldukça iyi takip eder , ancak derlendiği temel sisteme dayanır, bu nedenle platform farklılıkları oluşabilir. Son zamanlarda, "sonsuzluğa" ve "inf" e izin veren bir düzeltme uygulanmıştır , ancak bu çok az öneme sahiptir.
Aşağıdaki bölümler, IEEE kayan nokta aritmetiğini doğru bir şekilde uygulayan herhangi bir dil için eşit derecede geçerlidir, sadece Python'a özgü değildir.
Sonsuzlukla ve operatörlerden büyük >veya küçükten büyüklerle uğraşırken <, aşağıdakiler önemlidir:
+infdaha yüksek-inf-infdaha küçüktür+inf +infolduğu ne yüksek ne de düşük daha+inf-inf ne daha yüksek ne de daha düşük -infNaNyanlıştır ( infne daha yüksek ne de daha düşüktür NaN)Eşitlik için karşılaştırıldığında, zaman +infve +infeşittir gibidir -infve -inf. Bu çok tartışılan bir konudur ve sizin için tartışmalı gelebilir, ancak IEEE standardındadır ve Python böyle davranır.
Tabii ki, +infeşit değildir -infve NaNkendisi de dahil olmak üzere her şey eşit değildir NaN.
Sonsuzluğa sahip çoğu hesaplama, her iki işlenen de sonsuz değilse, işlem bölümü veya modulo olduğunda veya sıfır ile çarpıldığında, akılda tutulması gereken bazı özel kurallar vardır:
NaN0.0veya -0.0²'yi verir .NaN.inf - infsonuç tanımsızdır NaN:;inf - -infsonuç inf;-inf - infsonuç -inf;-inf - -inf, sonuç tanımsızdır: NaN.inf + infsonuç inf;inf + -infsonuç tanımsızdır NaN:;-inf + infsonuç tanımsızdır NaN:;-inf + -infsonuç -inf.math.pow, powya **da zor, olması gerektiği gibi davranmıyor. İki gerçek sayıyla sonuç, bir çift duyarlıklı şamandıra sığmayacak kadar yüksek olduğunda (sonsuzluk döndürmelidir), ancak giriş infveya olduğunda -infdoğru davranır ve ya infda döndürürse taşma istisnası atar 0.0. İkinci argüman olduğunda NaN, NaNilk argüman olmadığı sürece geri döner 1.0. Daha fazla sorun var, hepsi dokümanlarda ele alınmıyor .math.expile aynı sorunları yaşıyor math.pow. Taşma için bunu düzeltmenin bir çözümü şuna benzer bir kod kullanmaktır:
try:
res = math.exp(420000)
except OverflowError:
res = float('inf')Not 1: IEEE standardında tanımlandığı gibi, ek bir uyarı olarak, hesaplama sonucunuz az veya fazla taşarsa, sonuç bir düşük veya taşma hatası değil, pozitif veya negatif sonsuzluk: 1e308 * 10.0verim olacaktır inf.
Not 2: herhangi bir hesaplama nedeniyle NaNgetiri NaNve herhangi karşılaştırma NaNdahil NaNkendisi olduğunu false, kullanmak gerekir math.isnanbir numara gerçekten olup olmadığını belirlemek için işlev NaN.
Not 3: Python yazmayı desteklese de float('-NaN'), NaNdahili olarak oturum açma olmadığından işaret yok sayılır . Bölerseniz -inf / +inf, sonuç NaNdeğil -NaN(böyle bir şey yok).
Not 4: Python, derlendiği C veya Java kitaplığına dayandığı için yukarıdakilerden herhangi birine güvenmeye dikkat edin ve temeldeki tüm sistemler bu davranışı doğru bir şekilde gerçekleştirmez. Emin olmak istiyorsanız, hesaplamalarınızı yapmadan önce sonsuzluğu test edin.
¹) Son zamanlarda 3.2 sürümünden beri kullanılmaktadır .
²) Kayan noktalar pozitif ve negatif sıfırı destekler, dolayısıyla: x / float('inf')işaret ve -1 / float('inf')verimlerini -0.0, 1 / float(-inf)verimlerini -0.0, 1 / float('inf')verimlerini 0.0ve -1/ float(-inf)verimlerini korur 0.0. Buna ek olarak, 0.0 == -0.0birtrue , size gerçek olamayacak istemiyorsanız el işareti kontrol etmek zorunda.
-1 * float('infinity') == -inf
Yani yapar C99 .
Tüm modern işlemciler tarafından kullanılan IEEE 754 kayan nokta temsili, pozitif sonsuzluk (işaret = 0, exp = ~ 0, frac = 0), negatif sonsuz (işaret = 1, exp = ~ 0, frac = 0) için ayrılmış birkaç özel bit desenine sahiptir. ) ve birçok NaN (Sayı Değil: exp = ~ 0, frac ≠ 0).
Endişelenmeniz gereken tek şey: bazı aritmetik kayan nokta istisnalarına / tuzaklarına neden olabilir, ancak bunlar sadece bu "ilginç" sabitlerle sınırlı değildir.
OverflowError.
Şimdiye kadar kimsenin bahsetmediği bir uyarı buldum. Pratik durumlarda sık sık ortaya çıkıp çıkmayacağını bilmiyorum, ama burada tamlık uğruna.
Genellikle, bir sayı modulo sonsuzluğunun hesaplanması kendisini bir kayan nokta olarak döndürür, ancak bir kesir modulo sonsuzluğu geri döner nan(bir sayı değil). İşte bir örnek:
>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan
Python hata izleyicide bir sorun bildirdim. Https://bugs.python.org/issue32968 adresinde görülebilir .
Güncelleme: Bu Python 3.8'de düzeltilecektir .
ÇOK KÖTÜ BİR CAVEAT: Zero Bölümü
bir 1/xkesirde, x = 1e-323öyle infama ne zaman x = 1e-324ya da az atıyorZeroDivisionError
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
bu yüzden dikkatli olun!
1e309, olarak yorumlanacağını+infve-1e309olarak yorumlanacağını unutmayın-inf.