金光です。

福岡、行ってました。返事、遅くなってすいませんス。


> [mailto:ruby-math-admin / ruby-lang.org] On Behalf Of 正木 功
> Sent: Monday, June 25, 2001 1:20 PM
> 正木です。
> 
> "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 ですが、仕様をどうするか考慮中です。

これで、ひとつ文章を書きませんすか???



M.Kanemitsu
―――――――――――――――
金光雅夫 masao-k / a-net.email.ne.jp

http://www.ne.jp/asahi/masao-k/home/
http://www14.freeweb.ne.jp/art/soshikon/
http://www15.freeweb.ne.jp/computer/ruby256/
〒216-0031 川崎市宮前区神木本町5-14-12
自宅: 044-877-5006
携帯: 090-2753-5292