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

+3


source to share


2 answers


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)

      

+5


source


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).

+1


source







All Articles