From: gotoken@... (GOTO Kentaro) Date: 1999-02-17T17:49:01+09:00 Subject: [ruby-dev:5203] Re: Bigfloat [compare to NaN] ごとけんです Fixfraction を完成させてから参入しようと思ってたのですが 時間がとれないので,ちょっとだけ (-.-; # えぐちさんのパワーがすごくて,まいっちんぐ (^^;;; In message "[ruby-dev:5200] Bigfloat [compare to NaN]" on 99/02/17, 石塚圭樹 writes: >けいじゅ@日本ラショナルソフトウェアです. >>keiju> ここなんですが, PRECの違うBigfloatについてまだ考慮がなされていませんね. > >>そうなんです。 >>実は、prov の大きい方に合わせるというアイディアを持っていてのですが、 >>実装には移ってないです。 > >provですか?? > >そういえば, > > def +(other) > case other > when Bigfloat > #break > when Integer, Rational, Float > other = Bigfloat(other) > ^^^^ > >ってなっていますよね. 有効桁数の低いものから高いものにしても意味がない >ので, 逆の方が良いと思っているんですが? > >Bigfloat間でも PRECの低い方にあわせた方が良いと思っているんですが. えっと,少なくとも IEEE では異なる幅の数の演算結果は 広い方にせよなってまして,少なくとも近所の物理計算屋に 聞いてみてもそれが当然と思っていますし,僕も現状では 普及してる考え方だと思います. # 石塚さんがエントロピーを使って説明されましたが,一応, # 統計力学の単位をとったモノとしてはそんな孤立系の事情を # 持ち出されても…と思います. >でも, 最後の案は, Presicionと相性がすごく悪いのでやめましょう. >Presicionはクラスが1つの確定した精度を持たないと困るみたいです. > ># ですよね? >> ごとけんさん そう思います.よく考えてないので断片的ですが, def Bigfloat(mantissa_size, exponent_size, base) klass = Class.new(Bigfloat) klass.module_eval <<-EOS MANTISSA_SIZE = mantissa_size EXPONENT_SIZE = exponent_size BASE = base def initialize(num, exponent) @obj = Bigfloat.new(num, exponent, MANTISSA_SIZE, EXPONENT_SIZE, BASE) end EOS ... end のようなインターフェイス,つまり Bigfloat.new を呼ぶ時点で 精度を指定する必要があると思います.これのインスタンスの 素性は kind_of? 等では分かりませんが,例えばクラスメソッド として,mantissa_size 等を用意するようなプロトコルを確定 すればよいと思います. それと,上のようなインターフェイスにすれば必要ないと 思うですが,クラス定数の継承については以下のような 感じで出来るんじゃないでしょうか?? module Const def Const.append_features(mod) super if mod.type == Module mod.module_eval "CONST = []" elsif mod.kind_of? Class unless mod.superclass.constants.include?("CONST") mod.module_eval "CONST = []" else mod.module_eval "CONST = self.superclass::CONST" end end private def mod.const_setup return nil if defined?(self::CONST) if self.superclass.constants.include?("CONST") self.module_eval "CONST = self.superclass::CONST" else self.module_eval "CONST = []" end end public def mod.const self.const_setup self::CONST end def mod.const_add(x) self.const_setup return self::CONST if self::CONST.include?(x) self::CONST.push x end def mod.const_delete(x) self.const_setup self::CONST.delete(x) self::CONST end end end class Hoge include Const end class Boge < Hoge end == 実行例 Hoge::CONST ==>[] Hoge.const_add "foo" ==>["foo"] Boge.const_add "bar" ==>["foo", "bar"] Boge::CONST ==>["foo", "bar"] 本質的でない要素も入ってますがあくまで感じということで (^^;; この手のテクを使わないなら, class Class; include SomeConst; end などとして,全部のクラスに感染させる必要があると思います. -- gotoken