Reputation: 1047
This is not actually a problem, it is more something curious about floating-point arithmetic on Python implementation.
Could someone explain the following behavior?
>>> 1/1e-308
1e+308
>>> 1/1e-309
inf
>>> 1/1e-323
inf
>>> 1/1e-324
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero
It seems that 1 divided by a number near to zero is inf
and if it is nearer to a ZeroDivisionError
is thrown. It seems an odd behavior.
The same output for python 2.x/3.x.
EDIT: my main question here is why we get inf
for some range and not ZeroDivisionError
assuming that python seems to consider as zero 1e-309
Upvotes: 5
Views: 1964
Reputation: 4528
Minimum value that can be used as float numer in Python is :
2.2250738585072014e-308
Python uses double-precision floats, which can hold values from about 10 to the -308 to 10 to the 308 power.
Wikipedia - double precision floating point format
Actually, you can probably get numbers smaller than 1e-308 via denormals,But there is a significant performance hit to this. I found that Python is able to handle 1e-324
but underflows on 1e-325
and returns 0.0
as the value.
Upvotes: 3
Reputation: 17542
Most of the things have already been explained by Dolda2000 in his answer. Yet it might be helpful to see this.
>>> 1e-308
1e-308
>>> 1e-309
1e-309
>>> 1e-323
1e-323
>>> 1e-324
0.0
As you can see 1e-324
is equal to 0.0
in python implementation. As Dolda2000 put it very nicely: that number is simply too small to be represented even as a denormal, so that float literal is effectively equal to zero
Upvotes: 2
Reputation: 25855
This is related to the IEEE754 floating-point format itself, not so much Python's implementation of it.
Generally speaking, floats can represent smaller negative exponents than large positive ones, because of denormal numbers. This is where the mantissa part of the float is no longer implicitly assumed to begin with a 1, but rather describes the entire mantissa, and begins with zeroes. In case you don't know what that is, I'd suggest you read up about how floats are represented, perhaps starting here.
Because of this, when you invert a denormal number, you may end up with a positive exponent too large to represent. The computer then gives you inf
in its place. The 1e-308
in your example is actually also denormal, but still not small to overflow when inverted (because among normal numbers, the standard actually allows for slightly larger positive than negative exponents).
In case of 1e-324
, that number is simply too small to be represented even as a denormal, so that float literal is effectively equal to zero. That's why you get division by zero. The smallest representable 64-bit float is (slightly below) 5e-324
.
Upvotes: 8