floating point range generator

Carl Banks imbosol at aerojockey.com
Mon Jul 28 04:22:59 CEST 2003

Paul Rubin wrote:
> I needed this for something I was doing just now.  It came out pretty
> enough that I thought I'd post it.  It's like xrange, except for floating
> point values.
>    def frange(start, stop, step=1.0):
>        sign = cmp(0, step)
>        while cmp(start, stop) == sign:
>            yield start
>            start += step

It's a nice little iterator.  Three problems, though:

1. It can accumulate rounding errors
2. It can return an integer on the first iteration (minor)
3. The last iteration might not happen because of floating point
   uncertainties, even if rounding errors are minimized

A more robust version would look something like this (but it still has
problem #3):

    def frange(start, stop, step=1.0):
        sign = cmp(0,step)
	for i in xrange(sys.maxint):
            v = start+i*step
	    if cmp(v,stop) != sign:
            yield v

The most robust way to handle this is to iterpolate, i.e., instead of
passing start, stop, and step, pass start, stop, and n_intervals:

   def interiter(start, stop, n_intervals):
       diff = stop - start
       for i in xrange(n_intervals+1):
           yield start + (i*diff)/n_intervals

An IEEE 754 (whatever) geek can probably point out even more accurate
ways to do these.


More information about the Python-list mailing list