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')
inf
Bir hakkında bilmek daha iyidir, böylece değeri, alışılmadık semantik ile çok özel bir değer olarak kabul edilir OverflowError
ziyade bir olmasındansa hemen bir istisna yoluyla inf
sessizce 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 inf
ya da olduğunda -inf
, ya 0.0
da 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:
+inf
daha yüksek-inf
-inf
daha küçüktür+inf
+inf
olduğu ne yüksek ne de düşük daha+inf
-inf
ne daha yüksek ne de daha düşük -inf
NaN
yanlıştır ( inf
ne daha yüksek ne de daha düşüktür NaN
)Eşitlik için karşılaştırıldığında, zaman +inf
ve +inf
eşittir gibidir -inf
ve -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, +inf
eşit değildir -inf
ve NaN
kendisi 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:
NaN
0.0
veya -0.0
²'yi verir .NaN
.inf - inf
sonuç tanımsızdır NaN
:;inf - -inf
sonuç inf
;-inf - inf
sonuç -inf
;-inf - -inf
, sonuç tanımsızdır: NaN
.inf + inf
sonuç inf
;inf + -inf
sonuç tanımsızdır NaN
:;-inf + inf
sonuç tanımsızdır NaN
:;-inf + -inf
sonuç -inf
.math.pow
, pow
ya **
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ş inf
veya olduğunda -inf
doğru davranır ve ya inf
da döndürürse taşma istisnası atar 0.0
. İkinci argüman olduğunda NaN
, NaN
ilk argüman olmadığı sürece geri döner 1.0
. Daha fazla sorun var, hepsi dokümanlarda ele alınmıyor .math.exp
ile 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.0
verim olacaktır inf
.
Not 2: herhangi bir hesaplama nedeniyle NaN
getiri NaN
ve herhangi karşılaştırma NaN
dahil NaN
kendisi olduğunu false
, kullanmak gerekir math.isnan
bir numara gerçekten olup olmadığını belirlemek için işlev NaN
.
Not 3: Python yazmayı desteklese de float('-NaN')
, NaN
dahili olarak oturum açma olmadığından işaret yok sayılır . Bölerseniz -inf / +inf
, sonuç NaN
değ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.0
ve -1/ float(-inf)
verimlerini korur 0.0
. Buna ek olarak, 0.0 == -0.0
birtrue
, 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/x
kesirde, x = 1e-323
öyle inf
ama ne zaman x = 1e-324
ya 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ı+inf
ve-1e309
olarak yorumlanacağını unutmayın-inf
.