python-3.xinteractive-shell

Why does counting down in decimals result in a xxx.9999999999999999999x?


import time
def timer():
    a = 300.0
    while a > 0: #stopes at 0
        print(a)
        time.sleep(0.11) #for roughly 100 millisecond
        a = a - 0.1
timer()

I made a piece of code that counts down 1/10 per 0.100 seconds (roughly. it has to be more than 0.100 or the script will ignore it). However, output looks like this:

300.0
299.9
299.79999999999995
299.69999999999993
299.5999999999999
299.4999999999999
299.39999999999986
299.29999999999984
299.1999999999998
299.0999999999998
298.9999999999998
298.89999999999975
298.7999999999997
298.6999999999997
298.5999999999997
298.49999999999966
298.39999999999964
298.2999999999996
298.1999999999996
298.09999999999957
297.99999999999955
297.8999999999995
297.7999999999995
297.6999999999995
297.59999999999945
297.49999999999943
297.3999999999994
297.2999999999994
297.19999999999936
297.09999999999934
296.9999999999993
296.8999999999993
296.7999999999993
296.69999999999925
...

Why? Is there a fix?


Solution

  • You can actually use a python function called round. the round function will effectively round-out the 9999999... and only display what you want.

    A revised version of code would be:

    import time
    def timer():
        for a in range(3000,0,-1):
            print(round(a*.1, 1))
            time.sleep(0.101) #for roughly 1 millisecond
    
    
    timer()
    

    To use the round function, you do this:

    round([variableornumber]*.[float], [numberofdecimals]) #in this example, its limited to 1
    

    Another way to print while using round:

    print(round([variableornumber]*.[float], [numberofdecimals]))
    

    The reason python creates the 999999999999... is because python cannot create a precise fraction of 1/10 in base 2.

    15.Floating Point Arithmetic: issues and limitations--python 3.8.2