>From: matz / ruby-lang.org (Yukihiro Matsumoto)
>Subject: [ruby-math:00740] Re: Fixes for the new step methods in the range.c & numeric.c

> 以下のようなメールがruby-talkに来たのですが、私にはどこがどう違うのか
> 良く分かりませんでした。もしよければ知恵を貸していただけませんか?

英語にするのが面倒なのでこっちに書きます。

> In message "Fixes for the new step methods in the range.c & numeric.c"
>     on 02/05/06, chr_rippel / gmx.net <chr_rippel / gmx.net> writes:
>
> |The patch for the step method in numeric.c adds a sequence 
> |end point adjustment strategy - #step_fuzzyness measures the
> |``fuzzyness'' of step-length additions around the end-point
> |and adds a safety margin (there exist probably much better 
> |step_fuzzyness measures) - in pure Ruby:  

float.step(endpoint,step) と引数を渡したとすると、最終 n 回目
(0から始めて) のイテレータ呼び出しのとき、n*step+self の値が 
endpoint±fuzzyness の間に来たら、呼び出し値として n*step+self 
ではなく endpoint を強制的に使うということらしいです。こうすると
最終値が引数で渡した endpoint より少しオーバーするという気持悪さ
がなくなります。しかしこれだと最終回とその前の値の差が step の値
からずれるので、数値計算などの使い道にとってはうれしくありません。
挙動が外から少しわかりにくいのも気になります。

コードは Ruby で書いた方しか見ていませんが、

> |class Float
> |    def test_step(b,s)
> |      n = ((b - self)/ s).round
> |      last = n*s + self
> |      
> |      fuzzyness = step_fuzzyness(n,s)
ここは単に、
         fuzzyness = (b-self).abs * EPSILON   # EPSILON=2.0**(-52)
とすべきかと思います。
> |      if (s > 0 && last > b + fuzzyness) || \
> |         (s < 0 && last < b - fuzzyness)
ここは、
         if (s > 0 && last-b > fuzzyness) || \
            (s < 0 && last-b < -fuzzyness)
として、
> |         n-=1
> |         last = n*s + self
> |      end
> |      
> |      if (last - b).abs < fuzzyness
ここを、
         if (last - b).abs <= fuzzyness
としないと、last>b となる場合がでてきます。
> |        last = b
> |      end
> |        
> |      (n-1).times {|i| yield i*s + self }
> |      yield last
> |	self
> |    end
snip
> |end

田中昌宏