How to get Python division by -0.0 and 0.0 to result in -Inf and Inf, respectively?

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

I completely agree with @Mark Ransom, except that I would use try instead:

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

The reason I recommend this is that if you are performing this function many times, you don't have to waste time each iteration checking if the value is zero before you attempt the division.

EDIT:

I have compared the speed of the try compared to the if function:

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

Here is the tests:

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

Here is the result:

try: 0.573683023453
if: 0.610251903534

This indicates the try method is faster, at least on my machine.


Here is a solution that handles all the edge cases correctly, at least as far as I'm aware of:

def divide(a: float, b: float) -> float:
    try:
        return a/b
    except:
        return a*math.copysign(math.inf, b)

assert divide( 1,  1) ==  1
assert divide( 1, -1) == -1
assert divide(-1,  1) == -1
assert divide(-1, -1) ==  1
assert divide( 1,  0.0) >  1e300
assert divide( 1, -0.0) < -1e300
assert divide(-1,  0.0) < -1e300
assert divide(-1, -0.0) >  1e300
assert math.isnan(divide( 0.0,  0.0))
assert math.isnan(divide( 0.0, -0.0))
assert math.isnan(divide(-0.0,  0.0))
assert math.isnan(divide(-0.0, -0.0))

In the case that b is a zero, it basically splits the division a/b into a * (1/b) and implements 1/b via copysign(). The multiplication does not throw when its arguments are 0*inf, instead it correctly yields a NAN.