Python will be 0.0 after too many divisions
So I have the following code:
half= 1/2.0
print(half)
for x in range(1,1075):
half=half/2.0
print(half)
But right in the last part of the loop, python decides that half is now 0.0
1.265e-321
6.3e-322
3.16e-322
1.6e-322
8e-323
4e-323
2e-323
1e-323
5e-324
0.0
Is the python limit reached? Do I need to install a package to go further? I'm not sure why this is happening, but my guess is that python has reached the limit
source to share
TL; DR : Try Fraction
half = Fraction(1, 2)
for x in range(1, 1075):
half = half / 2
print(half)
will give
1/4 1/8 ... 1/202402253307310618352495346718917307049556649764142118356901358027430339567995346891960383701437124495187077864316811911389808737385793476867013399940738509921517424276566361364466907742093216341239767678472745068562007483424692698618103355649159556340810056512358769552333414615230502532186327508646006263307707741093494784 1/404804506614621236704990693437834614099113299528284236713802716054860679135990693783920767402874248990374155728633623822779617474771586953734026799881477019843034848553132722728933815484186432682479535356945490137124014966849385397236206711298319112681620113024717539104666829230461005064372655017292012526615415482186989568
You can find out the smallest available positive float
with
>>> import sys
>>> sys.float_info.min
2.2250738585072014e-308
then after your example we find that
>>> 2 * sys.float_info.min > pow(2, -1074)
True
i.e. the next division by 2 appears to be less than the smallest positive available float
.
Btw their difference is
>>> diff = 2 * sys.float_info.min - pow(2, -1074)
>>> diff
4.4501477170144023e-308
but I wonder what
>>> diff == 2 * sys.float_info.min
False
and
>>> diff / 2 == sys.float_info.min
True
P. S .: separating Fraction
objects float
will not give usfloat
>>> half = Fraction(1, 2)
>>> half = half / 2.0
>>> type(half)
<class 'float'>
so your code dividing by 2.0
will give the same result and to work properly with Fraction
you have to add / subtract / divide / multiply it with int
or other Fraction
like
half = Fraction(1, 2)
for x in range(1, 1075):
half = half / Fraction(2.0)
print(half)
P. PS : There is a convention to use underscore as a name for an unused object, so it's better to write
half = Fraction(1, 2)
for _ in range(1, 1075):
half = half / 2
print(half)
source to share
Yes, essentially you have reached the limit of Python. Decimal numbers lose precision as you continue.
One possible way would be to use the Fraction class as suggested by Azat.
However, you can also use the Decimal class .
Here's an example from the page above. This treats the number as an object and not as a primitive / built-in variable:
>>> from decimal import *
>>> getcontext().prec = 6
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')
>>> getcontext().prec = 28
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571428571428571428571429')
Line getcontext().prec = 6
is the one that sets the precision. You can change the number 6
to whatever you need.
Typically precision to the 324th decimal place (as in your example) is not required, so Python only stores a few digits as binary fractions . Using fraction or decimal place classes allows for more functionality, but can also slow down your code significantly if you reuse it (for example, in loops).
source to share