2013-04-25 11 views
9

Sonuç olarak + Inf ve -Inf değerini görmeyi beklediğim 0.0 veya -0.0'a bölündüğünün makul olduğu bir durum var. Python'un her iki durumda daPython bölümünü -Inf ve Inf ile sonuçlandırmak için -0.0 ve 0.0 nasıl alınır?

'u atmaktan hoşlandığı görülmektedir. Açıkçası, bunu 0,0 için bir testle tamamlayabileceğimi düşündüm. Ancak, +0.0 ile -0.0 arasında ayrım yapmanın bir yolunu bulamıyorum. (FYI, yazarak ya da -1.0 * 0.0 gibi genel hesaplamalar ile kolayca -0.0 alabilirsiniz).

IEEE, her şeyi çok güzel bir şekilde ele alıyor, ancak Python iyi düşünülmüş IEEE davranışını gizlemek için acı çekiyor gibi görünüyor. Aslında, 0.0 == -0.0 aslında bir IEEE özelliğidir, bu yüzden Python'un davranışı ciddiye alır. C, Java, Tcl ve hatta JavaScript'te mükemmel çalışır.

Öneriler?

cevap

11
from math import copysign 

def divide(numerator, denominator): 
    if denominator == 0.0: 
     return copysign(float('inf'), denominator) 
    return numerator/denominator 

>>> divide(1, -0.0) 
-inf 
>>> divide(1, 0) 
inf 
+1

+1, kesinlikle benim çözümümden daha temiz. – Blender

+1

Çok güzel - bu şekilde yapmayı düşünmezdim;) +1 –

8

yerine try kullanacağı dışında tamamen, @ Mark Ransom katılıyorum:

def f(a, b): 
    try: 
     return a/b 
    except ZeroDivisionError: 
     return copysign(float('inf'), denominator) 

karşımdakinin bu fonksiyonu defalarca performans gösterip, yok olmasıdır tavsiye nedeni Eğer bölüm denemeden önce değeri sıfır ise her yineleme kontrol zaman kaybı gerekir.

DÜZENLEME:

Ben if işlevine göre try hızını karşılaştırdık: Burada

s = time.time() 
[f(10, x) for x in xrange(-1000000, 1000000, 1)] 
print 'try:', time.time()-s 
s = time.time() 
[g(10, x) for x in xrange(-1000000, 1000000, 1)] 
print 'if:', time.time()-s 

sonucudur: Burada

def g(a, b): 
    if b == 0: 
     return copysign(float('inf'), b) 
    else: 
     return a/b 

testler geçerli:

try: 0.573683023453 
if: 0.610251903534 

Bu, makinemde en az try yönteminin daha hızlı olduğunu gösterir.

+0

'try ... except' aslında 'if''den daha yavaştır. – Blender

+1

@Blender Sadece buna katılmayan bazı testler yaptım; Aksi halde gösteren testleriniz var mı? – SethMMorton

+0

Burada yapıştırılamıyor çünkü 30 satır gibi görünüyor, ama [ekran görüntüsü] (http://i.imgur.com/sqgbwJF.png). – Blender

2

gmpy2 kitaplığı, isteğe bağlı bir kesinlikli tip sağlar ve ayrıca IEEE-754 kural dışı durum davranışını denetlemenize de olanak sağlar.

>>> import gmpy2 
>>> from gmpy2 import mpfr 
>>> mpfr(1)/mpfr(0) 
mpfr('inf') 
>>> mpfr(1)/mpfr(-0) 
mpfr('inf') 
>>> mpfr(1)/mpfr("-0") 
mpfr('-inf') 
>>> gmpy2.get_context().trap_divzero=True 
>>> mpfr(1)/mpfr(0) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
gmpy2.DivisionByZeroError: 'mpfr' division by zero in division 

Yasal Uyarı: Gmpy2'yi koruyorum.

+0

Teşekkürler. Keyfi hassasiyetten yararlanacak başka bir proje için gmpy2'yi kontrol edeceğim.Şu anki projem, en yüksek performansa (iç döngü malzemesi) ihtiyaç duyuyor ve keyfi bir doğruluk gerektirmiyor. – Chuck

İlgili konular