[Tutor] range function and floats?
Steven D'Aprano
steve at pearwood.info
Wed Jan 5 12:14:46 CET 2011
Alan Gauld wrote:
>> ...this is more about learning how the range function and floats work
>> than about writing a super-efficient program.
>
> Unfortunately they don't work together.
>
> range(0.1,0.5,0.1) -> [0.1,0.2,0.3,0.4] doesn't work
> you need to do:
>
> for n in range(1,5): use( n/10 )
There are pitfalls in writing a range() equivalent for floats. Here's
one way that doesn't work:
def new_range(start, end, step):
# DON'T USE THIS!!!
x = start
while x < end:
yield x
x += step
Here it seems to work:
>>> list(new_range(5, 10, 0.25))
[5, 5.25, 5.5, 5.75, 6.0, 6.25, 6.5, 6.75, 7.0, 7.25, 7.5,
7.75, 8.0, 8.25, 8.5, 8.75, 9.0, 9.25, 9.5, 9.75]
(Remember that the end argument is excluded!)
But here it fails:
>>> L = list(new_range(5, 10, 0.1))
>>> L[-1] == 9.9 # expect the last value to be 9.9
False
>>> L[-1] == 10.0 # maybe it's 10 then
False
In fact, the last value is a totally unexpected 9.9999999999999822. Such
is the perils of floating point rounding errors.
I've written a recipe for a float range which I hope avoids as many of
these problems as possible. It isn't possible to avoid *all* rounding
error when doing floating point calculation, but this should minimize them:
http://code.activestate.com/recipes/577068-floating-point-range/
As a bonus, it allows you to choose whether the start and end points are
included or excluded.
--
Steven
More information about the Tutor
mailing list