けいじゅ@日本ラショナルソフトウェアです.

In [ruby-math:00788] the message: "[ruby-math:00788] Re:
Rational#to_f", on Dec/10 03:35(JST) masaki writes:

>正木です。

>|この件ですが, Floatのフォーマットを意識した変換の方が良いと思うのです
>|が? つまり, 2進法をベースにした変換というか...
>
>私は逆に出来るだけ Float の実装に依存しない書き方の方が良いと思います
>が。

あ. 正木さんのコードを見ていて気が付きました. 分母や分子がfloatにする
とinfinitになる場合を気にしているのですね?

てっきりわたしは, 

 @numerator.to_f/@denominator.to_f

で丸め誤差が三回発生(to_f2回, Float#/)しているのが気になっているのかと
思っていました.

最後に添付するようなものはいかがでしょうか?

やっていることは, 除算を整数の範囲で行って最後にFloatに変換しています.
この方式だと, Floatで表現出来る値にもっとも近いFloatに変換できると思い
ます. Rational(2**1000,3**650)で比較しましたが, 正木さんのものよりも精
度は高いようです.

  def to_f
    return -(-self).to_f if self < 0
#    return 1.0/Rational(@denominator, @numerator).to_f if @numerator < @denominator
    
    n_exp = 0
    n = @numerator
    n_exp = (n.size - 4 - 32) * 8
    n >>= n_exp

    d_exp = 0
    d = @denominator
    d_exp = (d.size - 4 - 8) * 8
    d >>= d_exp

    Math.ldexp(((n + d/2)/d).to_f, n_exp - d_exp)
#    ((n + d/2)/d).to_f*2.0**(n_exp-d_exp)
  end

__
..............................石塚 圭樹@日本ラショナルソフトウェア...
----------------------------------->> e-mail: keiju / rational.com <<---