“Alan Chen” alan@digikata.com wrote in

…

I’m guessing because of the inaccuracy of floats. If you define a step

size

smaller then the minimum accuracy of your range, the behavior becomes

undefined. For example if you did:

10E9.step(10E10, 10E-9)

The result would likely be an infinite loop (or maybe an underflow).

Actually 1.7 recently introduced steps for Floats - the algorithm

is something like

```
class Float
Eps = 2.0**(-52)
def step(e,s)
n = ((e - self) / s + Eps).floor
n.times { |i| yield self + i*s }
self
end
end
```

A ``problem’’ with this algorithm is that it does not give

you an accurate right boundary. For example

## ···

include Math

def accurate_right_boundary?

(E+3*PI).step(E,-PI) do |i|

return true if i == E

end

false

end

## p accurate_right_boundary?

will return false. An algorithm by Masaki to adjust the right

boundary (the last ``i’’) to E (I submitted a slight correction

of Masaki algorithm to allow for negative steps) was rejected

on the basis that this type of adjustment might be surprising

for the user.

Anyway the `adjustment situation'' most likely arises if one wants to subdivide a given interval [a,b] repectively [a,b) into`

n’’ equidistant pieces. Since one cannot (in cvs) iterate over

Float Ranges anymore (a good thing imo), it is tempting to

introduce something like

```
(3.0..7.0).sub_divided(4) { |i| p i }
```

along the lines of

class Range

def sub_divide(n)

# do some kind of argument checking

unless first.is_a?(Numeric) && last.is_a?(Numeric)

raise "…"

end

nf = n.to_f

unless exclude_end?

n.downto(0) do |i|

yield first*(i / nf) + last*((n - i)/nf)

end

else

n.downto(1) do |i|

yield first*(i / nf) + last*((n - i)/nf)

end

end

self

end

end

(this probably should work differently if Rationals

are present).

/Christoph