Hi!
I just discovered step, but if I can see (in 1.6) it works on just
integers:(
Is there any reason why it cannot handle floats?
Gergo
±[Kontra, Gergely @ Budapest University of Technology and Economics]-+
Email: kgergely@mcl.hu, kgergely@turul.eet.bme.hu |
URL: turul.eet.bme.hu/~kgergely Mobile: (+36 20) 356 9656 |
±------“Olyan langesz vagyok, hogy poroltoval kellene jarnom!”-------+
.
Magyar php mirror es magyar php dokumentacio: http://hu.php.net
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).
···
On Tue, Jun 11, 2002 at 02:42:33AM +0900, Kontra, Gergely wrote:
Hi!
I just discovered step, but if I can see (in 1.6) it works on just
integers:(
Is there any reason why it cannot handle floats?
Gergo
–
Alan Chen
Digikata LLC
http://digikata.com
“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