2013-04-25 48 views
9

我有一種情況,如果我將期望分別看到+ Inf和-Inf作爲結果,可以合理地劃分0.0或-0.0。似乎Python喜歡在任何一種情況下投擲一個如何讓Python除以-0.0和0.0分別導致-Inf和Inf?

ZeroDivisionError: float division by zero 

。很明顯,我想我可以簡單地用0.0來測試這個測試。但是,我無法找到區分+0.0和-0.0的方法。 (僅供參考,通過輸入或通過常用計算(例如-1.0 * 0.0)可以輕鬆獲得-0.0)。

IEEE處理這一切都很好,但Python似乎很難隱藏深思熟慮的IEEE行爲。事實上,0.0 == -0.0實際上是IEEE的一個特性,所以Python的行爲嚴重破壞了事情。它在C,Java,Tcl甚至JavaScript中都能很好地工作。

對此提出建議?

回答

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,絕對比我的解決方案更清潔。 – Blender 2013-04-26 00:14:52

+1

非常好 - 不會這麼想; +1)+1 – 2013-04-26 00:17:47

8

我完全@馬克贖金同意,但我會用try代替:

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

我建議是,如果你正在執行這個功能很多次了,你不這樣做的原因每次迭代都必須浪費時間檢查在嘗試除法之前值是否爲零。

編輯

我比較相比if功能try的速度:

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

下面是測試:

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 

下面是結果:

try: 0.573683023453 
if: 0.610251903534 

這表明try方法速度更快,至少在我的機器上。

+0

'try ... except'實際上比'if'慢。 – Blender 2013-04-26 00:20:02

+1

@Blender我只是做了一些不同意的測試;你有測試顯示,否則? – SethMMorton 2013-04-26 00:30:34

+0

我不能在這裏粘貼它,因爲它會佔用30行,但[這裏是截圖](http://i.imgur.com/sqgbwJF.png)。 – Blender 2013-04-26 00:40:49

2

gmpy2庫提供了一個任意精度浮點類型,並且還允許您控制IEEE-754異常行爲。

>>> 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 

聲明:我維護gmpy2。

+0

謝謝。我會檢查出gmpy2是否會受益於任意精度的另一個項目。我目前的項目需要最高性能(內循環的東西),並不需要任意的精度。 – Chuck 2013-04-26 06:49:17