Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does division near to zero have different behaviors in python?

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

like image 352
emartinelli Avatar asked Feb 15 '16 01:02

emartinelli


People also ask

How does Python handle division by zero?

You can't divide by zero! If you don't specify an exception type on the except line, it will cheerfully catch all exceptions. This is generally a bad idea in production code, since it means your program will blissfully ignore unexpected errors as well as ones which the except block is actually prepared to handle.

What will happen if you divide any number by zero in Python?

In Python, division by zero generates the exception ZeroDivisionError: division by zero. This is because in mathematics, division by zero is undefined.

What happens if you try to divide an integer value by zero in Python?

In mathematics, division by 0 is undefined. Because of this, Python will issue the above error when your code tries to accomplish this undefined expression.

Why is division not working in Python?

An input from the user is a string by default. In order to perform mathematical operations on an input, you need to either change it to an integer or a float using int() or float() respectively.


3 Answers

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.

like image 193
Dolda2000 Avatar answered Oct 21 '22 14:10

Dolda2000


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.

like image 3
ᴀʀᴍᴀɴ Avatar answered Oct 21 '22 13:10

ᴀʀᴍᴀɴ


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

like image 2
Sнаđошƒаӽ Avatar answered Oct 21 '22 14:10

Sнаđошƒаӽ