>From: matz / ruby-lang.org (Yukihiro Matsumoto)
>Subject: [ruby-math:00725] Re: $BBjL>K:$l$G$9 (^^;

> Floatに拡張したのは実際にそういう使い方をしたいという要望に
> 従ったものなので、「離散的な順序に限ったほうがよい」という判
> 断をする場合には、個人的には「その要望は却下」と言えるだけの
> 理由を欲しています。

私は離散的うんぬんというよりは、一般的な step は 
(first, n_times, step) の組から作るべきという考え方なんですが、...

Integer の step をそのまま Float に拡張した場合の問題は、
前にも言いましたが誤差から来ます。Float#step を

class Float
  def step(max,step)
    idx = self
    while idx <= max
      yield idx
      idx += step
    end
  end
end

と定義すると、(ループの条件を idx <= max としました)

 0.0.step( 10, 0.1 ) {|i| p i }

は max=10 まで繰り返されるのに対し、

 0.0.step( 12, 0.3 ) {|i| p i }

は 11.7 までしか繰り返されません。(私のマシンでは)
これは idx に積もった誤差のため、最後に 12.0000000000000071
という値になってしまうためです。
このように、どう動作するかが浮動小数点数の内部まで立ち入らないと
予想できないようなメソッドを*標準*で用意するというのは、あまり
望ましくはないと思いますがいかがでしょうか。
(ユーザが自己責任で用意するのは構わないと思いますが)

どうしても (first, max, step) の組から stepメソッドを作るなら、
以下のような感じにして欲しいです。

class Float
  EPSILON=2.2204460492503131E-16
  def step(max,step)
    n = (max-self)/step
    n = (n + n*EPSILON).floor + 1
    n.times{|i| yield i*step+self}
  end
end

単純に ((max-self)/step).floor を回数にしないのは、
ここでも誤差が入ってくるからです。

田中昌宏