From: Kazuhiro Yoshida Date: 2002-12-09T09:40:05+09:00 Subject: [ruby-list:36716] Re: 1.1 < 61.1 - 60.0 もりきゅうです。 Shin-ichiro HARA wrote: > 固定小数点数って具体的にはどうするのですか?そういうクラスを作る > のですよね。標準でほしいなあ。 こんなのかなと想像してみました。 とりあえず足し算と引き算だけ…。 Fixnum は小数点が右端にある固定小数点数クラスと考えられる。 そこで、数値を @n, 小数点の位置を @d とするクラスを考えて みました。でも、これだと小数点は動いてるな。全然違うのか。 未対応: * *, /, %, 精度 * coerce * 無限, 非数, 0 だめだめ。やっぱり BigFloat を使うのが吉か。 class Fix attr_reader :n, :d def initialize(n=0, d=0) @n = n @d = d norm end def Fix.new_str(str) if str.index('.') Fix.new str.delete('.').to_i, -(str.size - str.index('.') - 1) else Fix.new str.to_i, 0 end end def to_s str = @n.to_s if @d < 0 if str.size > -@d str[str.size-(-@d),0] = '.' else str[0,0] = '0.' << '0'*(-@d-1) end else str << '0'*@d end str end def value=(v) @n = v norm end def value @n * 10 ** @d end alias to_f value def to_i @d < 0 ? 0 : @n end def +(other) case other when Fix x = other when Fixnum x = Fix.new other, 0 else raise TypeError end case @d <=> x.d when +1 Fix.new @n * 10 ** (@d - x.d) + x.n, x.d when -1 Fix.new @n + x.n * 10 ** (x.d - @d), @d else Fix.new @n + x.n, @d end end def +@ Fix.new(+@n, @d) end def -@ Fix.new(-@n, @d) end def -(other) self + -other end def <=>(other) case @d <=> other.d when +1 @n * 10 ** (@d - other.d) <=> other.n when -1 @n <=> other.n * 10 ** (other.d - @d) else @n <=> other.n end end def check raise TypeError unless @n.is_a? Fixnum raise TypeError unless @d.is_a? Fixnum end def norm check while @n%10 == 0 @n /= 10 @d += 1 end end end a = Fix.new 1,0 p a puts a b = Fix.new 2,3 p b puts b c = Fix.new 2001 p c puts c p a+b p b+a p a<=>b p b<=>a p a<=>c p c<=>a p b<=>c p c<=>b p c<=>a+b p a+b<=>c p Fix.new 611,-1 p Fix.new 600,-1 x = Fix.new_str "61.1" p x p +x p -x y = Fix.new_str "60.0" p y z=x-y p z puts z w=z-1 p w puts w q = Fix.new_str "-1" p q puts q ---- YOSHIDA Kazuhiro moriq@moriq.com http://www.moriq.com/