正木です。

In message "[ruby-math:00462] Re: class Real"
"KANEMITSU Masao" <masao-k / a-net.email.ne.jp> wrote:

|これって、どんなときどういう風に使うんですか?
|ちょっとアプリを見せてもらえません?


実数を実数として扱いたいときに使います。
有理数を扱うときは Rational を使うのと同じです。
Float では精度が足りない時や範囲外の時は勿論ですが、そうでなくても
実数に対して Float を使うのが気持がわるい時は、時間がかかるのさえ
我慢すれば、Float を使わずにすますことができます。
使い方は x が有理数なら
z=Real.sin(x)
Real に対しては
z.log
の様に書きます。
(関数は今のところ sqrt,exp,log,sin,cos 予定としては Gamma,zeta,Bessel etc.)
近似有理数は、誤差を eps として
z.approx(eps)
小数表現は、基数を r(<=16) 桁数を m として
z.printd(m,r)
とします。
(但し前 mail に書いた理由で
p ((Real.pi/4).tan==1)
は、Real.error=eps (>0) として誤差 eps の範囲でしか評価できません。)


Ruby の Float の精度を調べてみると
p 2.0**m (m=-1075..1024) の結果と
(2**52*(4.0/3)).printd(4) => 6004799503160661.0000
とから、符号 1bit 指数部 11bit 仮数部 52bit(省略された 1bit があるので
精度は 53bit) 計 64bit らしいと推測できます(i386 では演算のときのみ
80bit のregister を使用)。

次のように Real,Rational,Float 間の変換 method を定義します。
(現在の Rational#to_f  Rational#round は正しい値を返しません)
----
class Real
  def approx(eps=@@error,m=0)
    find{|x,e,i| e <= eps }[m]
  end
  def approxR(eps=@@error,m=0)
    find{|x,e,i| x!=0 && e/x.abs <= eps }[m]
  end
  def to_i
    a=(approx(1/2)+1/2).to_i
    (self<a)? a-1:a 
  end
  def round
    a=approx(1/2).to_i
    (self<a+1/2)? a: a+1
  end
  def to_f(m=52)
    approxR(2**-(m+1)).to_f(m)
  end
end

class Float
  def to_Rational(m=53)
    a,k=Math.frexp(self)
    (2**m*a).to_i/2**(m-k)
  end
end

class Rational
  def round
    (self+Rational(1,2)).to_i
  end
  alias to_f! to_f
  def to_f(m=52)
    x=self
    return -(-x).to_f(m) if x<0
    k=0
    k-=1 while 2**k*x > 2
    k+=1 until 2**k*x > 1
    n=m+k
    ((2**n*x).round/2**n).to_f!
  end
end
-----
(前 mail で書いた問題点のせいで、実数の値が整数の時は to_i が、
半整数の時は round が無限 loop になります。)
PI,E に対して試してみると
p Real.pi.to_f==Math::PI => true
p Real.exp(1).to_f==Math::E => true
p Real.sqrt(2).to_f==Math.sqrt(2) => true
となり一応うまくいっているようです。

当然のことですが Float の実体は有理数です。例えば
(1.0/3).to_Rational=6004799503160661/2**54
Math::PI.to_Rational==884279719003555/2**48
Math::E.to_Rational==6121026514868073/2**51
Math.sqrt(2).to_Rational==6369051672525773/2**52

Float は FPU(浮動小数点演算装置)を使うので非常に早いため、速度が必要な時は
使わざるを得ませんが、止むを得ず使うもので、好んで使うものではありません。
 
昔 FPU が付いていない CPU(i8086) を使っていたとき、 FPU を emulate するため
に多倍長浮動小数点の演算の program を assembler で書いて使っていました。
その当時は任意精度の実数は可能でも無限精度の実数は無理だと思っていました。
最近 Ruby でそれができると分かったので、色々試しているわけです。
本当の目標は true Complex ですが、仕様をどうするか考慮中です。