On Wed, Jan 5, 2011 at 5:14 AM, Steven D'Aprano <[email protected]> wrote:
> 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. As an alternative to floating point, you can use the Decimal module: import decimal def new_range(start, stop, step): x = decimal.Decimal(str(start)) step = decimal.Decimal(str(step)) while x < stop: yield x x += step x = list(new_range(5, 10, 0.1)) x[-1] == decimal.Decimal(str(9.9)) #True float(x[-1]) == 9.9 #True The decimal module allows you to get rid of those pesky floating point errors. See http://docs.python.org/library/decimal.html for more info. On a related note, if you're interested in working with rational numbers (1/23, 3/4, etc.) there is also a fraction module http://docs.python.org/library/fractions.html. HTH, Wayne
_______________________________________________ Tutor maillist - [email protected] To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
