2013-04-25 6 views
9

저는 + Inf와 -Inf를 각각 결과로 볼 것으로 예상되는 곳에서 0.0 또는 -0.0으로 나누는 것이 합리적 인 상황이 있습니다. 파이썬은 어느 경우 에나-0.0과 0.0으로 파이썬 나누기를 얻는 방법 -Inf와 Inf에서 각각 결과를 얻으려면 어떻게해야합니까?

ZeroDivisionError: float division by zero 

을 던지고있는 것 같습니다. 분명히, 나는 이것을 단순히 0.0의 테스트로 감쌀 수 있다고 생각했다. 그러나 나는 +0.0과 -0.0을 구별 할 수있는 방법을 찾을 수 없다. (당신은 쉽게 그것을 입력하거나 -1.0 * 0.0과 같은 일반적인 계산을 통해 -0.0을 얻을 수 있습니다.)

IEEE는이 모든 것을 매우 훌륭하게 처리하지만, 파이썬은 잘 생각한 IEEE 동작을 숨기기 위해 애쓰는 것처럼 보입니다. 사실, 0.0 == -0.0이라는 사실은 실제로 IEEE 기능이므로 파이썬의 동작은 심각하게 문제를 일으 킵니다. 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

+1

아주 멋지다 - 그런 식으로 생각하지 않을 것이다.) +1 –

8

내가 대신 try을 사용하는 것을 제외하고 내가 완전히 @ 마크 랜섬에 동의 :

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

난이이 기능을 여러 번 수행하는 경우, 당신은하지 않는 것이 추천 이유를 분할을 시도하기 전에 값이 0이면 각 반복을 시간 낭비해야합니다.

EDIT :

내가 if 기능에 비해 try의 속도를 비교 한 다음은

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 

의 결과이다 : 여기

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

을 시험이다 :

try: 0.573683023453 
if: 0.610251903534 

이는 적어도 내 컴퓨터에서는 try 메서드가 빠름을 나타냅니다.

+0

'try ... except'는 실제로'if'보다 느립니다. – Blender

+1

@Blender 방금 테스트에 동의하지 않았습니다. 그렇지 않으면 시험을 보입니까? – SethMMorton

+0

30 줄짜리지만, [스크린 샷] (http://i.imgur.com/sqgbwJF.png)과 같이 여기에 붙여 넣을 수 없습니다. – Blender

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