Search code examples
pythonfunctiongeneratorfloating-point-precision

Last decimal digit precision changes in different call of same generator function [python]


I created this generator function:

def myRange(start,stop,step):
    r = start
    while r < stop:
        yield r
        r += step

and I use it in two different ways. 1st:

for x in myRange(0,1,0.1):
    print x

Result:

0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0

2nd way to call the function:

a = [x for x in myRange(0,1,0.1)]

which results in:

[0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999]

Why are the values generated different?


Solution

  • It is not the order in which you called your generator, but the way you are presenting the numbers that caused this change in output.

    You are printing a list object the second time, and that's a container. Container contents are printed using repr(), while before you used print on the float directly, which uses str()

    repr() and str() output of floating point numbers simply differs:

    >>> lst = [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999]
    >>> print lst
    [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999]
    >>> for elem in lst:
    ...     print elem
    ... 
    0
    0.1
    0.2
    0.3
    0.4
    0.5
    0.6
    0.7
    0.8
    0.9
    1.0
    >>> str(lst[3])
    '0.3'
    >>> repr(lst[3])
    '0.30000000000000004'
    

    repr() on a float produces a result that'll let you reproduce the same value accurately. str() rounds the floating point number for presentation.