Generalized range

Michael Hoffman cam.ac.uk at mh391.invalid
Thu Apr 26 17:54:40 CEST 2007


tkpmep at hotmail.com wrote:
> I need to create ranges that can start and end with real numbers.
> Searching this newsgroup brought me to a function that I then modified
> as follows:
> 
> def myRange(iMin, iMax=None, iStep=1):
>     """Extends range to real numbers. Wherever possible, use Python's
> range .
>        In other cases, make the behavior follow the spirit of Python's
> range """
>    epsilon = 1.e-8
> 
>     if iMax == None and iStep == 1:
>         return range(int(iMin))
> 
>     elif type(iMin).__name__.lower()  in ('int', 'long') and \
>          type(iMax).__name__.lower()  in ('int', 'long') and \
>          type(iStep).__name__.lower() in ('int', 'long') and iStep !=
> 0:
>         return range( iMin, iMax, iStep)
> 
>     elif iMin <= iMax and iStep > 0:
>         return [ iMin+i*iStep for i in range( int(math.ceil((iMax -
> iMin - epsilon)/iStep)) )]
> 
>     elif iMin >= iMax and iStep < 0:
>         return [ iMin+i*iStep for i in range(-int(math.ceil((iMin -
> iMax + epsilon)/iStep)) )]
> 
>     else:
>         raise ValueError, 'Cannot construct a range with steps of size
> ' + str(iStep) + ' between ' + str(iMin) + ' and ' + str(iMax)
> 
> 
> The one part of  my implementation that has me a bit queasy (i.e.
> works in my current application, but I can see it misbehaving
> elsewhere) is the addition/subtraction of a fixed epsilon to ensure
> that my rounding goes the right way. A clean implementation would
> modify epsilon based on the achievable level of precision given the
> particular values of iMax, iMin and iStep. I suspect this requires a
> detailed understanding of the implementation of floating point
> arithmetic, and would appreciate hearing any thoughts you might have
> on gilding this lily.

In addition to the comments of Stargaming, most of which I agree with, I 
think you would be far better dropping the epsilon business and doing 
something like:

# requires that minimum <= maximum; swap values if necessary
res = minimum
while res < maximum:
     yield res
     res += step
-- 
Michael Hoffman



More information about the Python-list mailing list