正木です。

|[ruby-math:00788] Re: Rational#to_f

||[ruby-math:00786] Re: Rational#to_f
||From: keiju / rational.com
||
||けいじゅ@日本ラショナルソフトウェアです.
||
||この件ですが, Floatのフォーマットを意識した変換の方が良いと思うのです
||が? つまり, 2進法をベースにした変換というか...
|
|私は逆に出来るだけ Float の実装に依存しない書き方の方が良いと思いますが。

と書きましたが、 Float の除算が予想以上に信用出来ないことが分かりました
ので考えをあらためて、(Float の内部構造に依るので機種依存になるかも知れ
ませんが)2進法できちんと変換することにしました:

class Numeric
  def log2floor
    raise "not defined for self <= 0" if self <= 0
    case self
    when Integer
      return 0 if self==1
      return self.div(2).log2floor + 1 if size==4
      self.div(2**(8*(size-4))).log2floor + 8*(size-4)
    when Rational
      return floor.log2floor if self >= 1
      m=(1/self).floor.log2floor + 1
      (self*2**m).floor.log2floor - m
    when Float
      Math.frexp(self)[1]-1
    end
  end
end
class Rational
  def to_f # for intel 64 bit floating point
    m,n=52,1023
    e=abs.log2floor
    if e > m-n
      (self*2**(m-e)).round.to_f/2**(m-e)
    else
      (self*2**n).to_f/2**n
    end
  end
end