T
tkpmep
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.
Sincerely
Thomas Philips
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.
Sincerely
Thomas Philips