小林です。

亀レスで申し訳ありません。

----- Original Message -----
From: "石塚圭樹" <keiju / rational.com>
Subject: [ruby-dev:16715] Re: if Re: BigFloat

> >Complex/Rationalとも考えてみましょう.
>
> 考えるといってなんですが... Complex op BigFloat はComplex側で対応するの
> はよいとして、Rational op BigFloat は BigFloat側で対応すべきと思います.
>
> というのも,
>
>   Rational op BigFloat -> BigFloat
Rational op BigFloat -> Rational
BigFloat op Rational -> Rational
ではないでしょうか?
精度(有効桁)的には
 Float <= BigFloat(BigDecimal) <= Rational
と考えられるので、より精度の高いほうに合わ
せるのが自然と思うのですが?

> になるので, RationalがBigFloatの生成を知っているというのはおかしいと思う
> からです.
これは、BigFloat(以後BigDecimalにします)がRationalの
生成に置き換えても成立すると思いますので、

> ただ, BigFloatからみてもrational.rbを読み込んでもいないのに, Rationalの
> 対応のコードが入っているのも変なので,
と私も思います。「標準配布ならかまわない?」という
knu さんの意見も一理アリとは思いますが、require
しないといけないのがなんとも...

>
>   bigfloat-rational.rb
>
> のような相互変換のためのメソッドを集めたファイルを別に用意したらどうかと
> 思います。で, bigfloat側はrequireされたときにrationalが既に読み込まれて
> いたら bigloat-rational.rb を読み込み、逆にrationalがrequireされたときに、
> 既にbigfloatが読み込まれていたらbigloat-rational.rbを読み込むと.
BigDecimal ==> Rational の変換は常に可能ですが、精度
を落とさずに Rational ==> BigDecimal の変換は常に可能
というわけにいかないし、ここはユーザに気を使ってもらえ
ば良いような気がしてきました。
例えば、BigDecimal#to_r を BigDecimal から Rational に
(誤差無く)変換するメソッドとするなら、以下のようにすれ
ば取り合えず何とかなります。

require "bigdecimal"
require "rational"
class BigDecimal
    def to_r
       sign,digits,base,power = self.to_parts
       numerator = sign*digits.to_i
       denomi_power = power - digits.size # base is always 10
       if denomi_power < 0
          denominator = base ** (-denomi_power)
       else
          denominator = base ** denomi_power
       end
      Rational.new(numerator,denominator)
    end
end

# 逆は、BigDecimal#div等で最大有効桁を
# ユーザが指定する。

どうせ Rational と BigDecimal 共に require しなきゃ
いけないし、Rational と BigDecimal を常に意識しな
がら計算するケースはそれほど多くは無いと思うの
で、この程度で良いのではないでしょうか?

------------------
小林 茂雄
shigeo / tinyforest.jp