From: KIYONO Koichi Date: 2002-09-18T00:59:47+09:00 Subject: [ruby-list:35955] Re: 9.2 の数値が 9.199999999999999 はじめてメールいたします。きよの と申します。 On Tue, 17 Sep 2002 19:13:48 +0900 nobu.nakada@nifty.ne.jp wrote: > なかだです。 > > >  浮動小数点数を使う限り、多倍長になっても誤差が出るのは避けられないですよ > > ね?(誤差を少なくはできるとして) > > BigDecimalってのもありますね。あれ、BigFloatだっけ。 > > http://www.tinyforest.gr.jp/ruby/ruby.html#BIGFLOAT (簡易)BigDecimal クラスを作ってみました。 正規化(?)を行っていませんし、なにより割り算がかなりいいかげんです... が、それなりに動作します。 class BigDecimal def initialize(init) if init.is_a? BigDecimal @exponent = init.exponent @val = init.val else integer, fraction, = init.to_s.split('.') int_int = integer.to_i frac_int = fraction.to_i frac_int = -frac_int if int_int < 0 @exponent = if fraction.nil? then 0 else fraction.length end @val = int_int * (10 ** @exponent) + frac_int end end def to_i; @val / (10 ** @exponent) end def to_f; @val.to_f / (10 ** @exponent) end def to_s str = @val.to_s if @exponent != 0 str[0..-(@exponent+1)] + '.' + @val.to_s[-@exponent..-1] else str end end attr_accessor :val, :exponent def +(other) other = BigDecimal.new(other) unless other.is_a? BigDecimal if @exponent < other.exponent result = BigDecimal.new(self) result.val = @val * (10 ** (other.exponent - @exponent)) + other.val result.exponent = other.exponent else result = BigDecimal.new(other) result.val = other.val * (10 ** (@exponent - other.exponent)) + @val result.exponent = @exponent end result end def -(other) negative = BigDecimal.new(other) negative.val = -negative.val self + negative end def *(other) other = BigDecimal.new(other) unless other.is_a? BigDecimal result = BigDecimal.new(self) result.val *= other.val result.exponent += other.exponent result end def /(other) other = BigDecimal.new(other) unless other.is_a? BigDecimal result = BigDecimal.new(self * 10000000000) # must be improved... result.val /= other.val result.exponent -= (other.exponent - 10) result end end a = BigDecimal.new(5000000000) b = BigDecimal.new("123456789.123456789") p a, b p a.to_i, b.to_i p a.to_f, b.to_f p a.to_s, b.to_s print "** add\n"; result = a + b; p result, result.to_s print "** sub\n"; result = a - b; p result, result.to_s print "** mul\n"; result = a * b; p result, result.to_s print "** div\n"; result = a / b; p result, result.to_s --- KIYONO Koichi E-Mail: kiyono-k@nifty.com Web Site: http://homepage2.nifty.com/cat-chy/