Steven D'Aprano wrote: > I'm trying to generate a sequence of equally-spaced numbers between a > lower and upper limit. Given arbitrary limits, what is the best way to > generate a list of equally spaced floats with the least rounding error for > each point? > > For example, suppose I want to divide the range 0 to 2.1 into 7 equal > intervals, then the end-points of each interval are: > > (0.0)---(0.3)---(0.6)---(0.9)---(1.2)---(1.5)---(1.8)---(2.1) > > and I'd like to return the values in the brackets. Using Decimal or > Fraction is not an option, I must use floats. If the exact value isn't > representable as a float, I'm okay with returning the nearest possible > float. > > The width of each interval is: > > width = (2.1 - 0.0)/7 > > The relevant points can be calculated in either of two methods: > > #1 add multiples of the width to the starting value, 0. > > #2 subtract multiples of width from the ending value, 2.1. > > (Repeated addition or subtraction should be avoided, as it increases the > amount of rounding error.) > > Mathematically the two are equivalent, but due to rounding, they may not > be. Here's a run using Python 3.2: > >>>> [0.0 + i*width for i in range(8)] > [0.0, 0.3, 0.6, 0.8999999999999999, 1.2, 1.5, 1.7999999999999998, 2.1] > > The 4th and 7th values have rounding errors, the rest are exact. > > >>>> [2.1 - (7-i)*width for i in range(8)] > [0.0, 0.30000000000000027, 0.6000000000000001, 0.9000000000000001, > 1.2000000000000002, 1.5, 1.8, 2.1] > > The 2nd, 3rd, 4th and 5th values have rounding errors. Note that the 7th > value is exact here, but not above. > > Is there a way to pick between methods #1 and #2 (or some combination of > the two) without human intervention so as to minimise the rounding error? > Or is there some other way to generate equally-spaced floats? My efforts > at googling have not been helpful.
When I've done this with ints (usually in small embedded systems) I've always preferred low_limit + (total_width * i) / intervals since it does the rounding on the biggest numbers where proportional error will be least, and it's guaranteed to hit the low_limit and high_limit exactly (as exactly as they can be represented, anyway.) Mel. -- http://mail.python.org/mailman/listinfo/python-list