From: Fumiaki Sakamoto Date: 2014-04-23T18:15:00+09:00 Subject: [ruby-list:49813] Re: 小数点以下の表示で質問があります。 えぐちさま こちらお勧めの通り、sprintfの部分を下記のように書き換えて見ました。 test09.rbの内容です。 require 'rational' a = Rational(1, 10) b = Rational(9, 1) i = 1 c = Rational(0, 1) d = Rational(1, 1) while i < 20 do c = c + b * a * d stringoutput = sprintf("%18.16f %a(%a)", c, c, eval("0." + "9" * i)) print i," ", c," ", stringoutput, " 9 x 0.1 ** ", i ," = ", b * a * d, "\n" if i == 6 then e = 0.99999 + b * a * d stringoutput = sprintf("%18.16f %a(%a)", e, e, eval("0." + "9" * i)) print "=>", i, " ", stringoutput, " 0.99999 + 9 x 0.1 ** 6 = ", e, "\n" end if i == 7 then e = 0.999999 + b * a * d stringoutput = sprintf("%18.16f %a(%a)", e, e, eval("0." + "9" * i)) print "=>", i, " ", stringoutput, " 0.999999 + 9 x 0.1 ** 7 = ", e, "\n" end if i == 8 then e = 0.9999999 + b * a * d stringoutput = sprintf("%18.16f %a(%a)", e, e, eval("0." + "9" * i)) print "=>", i, " ", stringoutput, " 0.9999999 + 9 x 0.1 ** 8 = ", e, "\n" end i += 1 d *= a end 結果です。 %ruby test09.rb 1 9/10 0.9000000000000000 0x1.ccccccccccccdp-1(0x1.ccccccccccccdp-1) 9 x 0.1 ** 1 = 9/10 2 99/100 0.9900000000000000 0x1.fae147ae147aep-1(0x1.fae147ae147aep-1) 9 x 0.1 ** 2 = 9/100 3 999/1000 0.9990000000000000 0x1.ff7ced916872bp-1(0x1.ff7ced916872bp-1) 9 x 0.1 ** 3 = 9/1000 4 9999/10000 0.9999000000000000 0x1.fff2e48e8a71ep-1(0x1.fff2e48e8a71ep-1) 9 x 0.1 ** 4 = 9/10000 5 99999/100000 0.9999900000000000 0x1.fffeb074a771dp-1(0x1.fffeb074a771dp-1) 9 x 0.1 ** 5 = 9/100000 6 999999/1000000 0.9999990000000000 0x1.ffffde7210be9p-1(0x1.ffffde7210be9p-1) 9 x 0.1 ** 6 = 9/1000000 =>6 0.9999990000000001 0x1.ffffde7210beap-1(0x1.ffffde7210be9p-1) 0.99999 + 9 x 0.1 ** 6 = 0.9999990000000001 7 9999999/10000000 0.9999999000000001 0x1.fffffca501acbp-1(0x1.fffffca501acbp-1) 9 x 0.1 ** 7 = 9/10000000 =>7 0.9999998999999999 0x1.fffffca501acap-1(0x1.fffffca501acbp-1) 0.999999 + 9 x 0.1 ** 7 = 0.9999998999999999 8 99999999/100000000 0.9999999899999999 0x1.ffffffaa19c47p-1(0x1.ffffffaa19c47p-1) 9 x 0.1 ** 8 = 9/100000000 =>8 0.9999999900000001 0x1.ffffffaa19c48p-1(0x1.ffffffaa19c47p-1) 0.9999999 + 9 x 0.1 ** 8 = 0.9999999900000001 9 999999999/1000000000 0.9999999990000000 0x1.fffffff768fa1p-1(0x1.fffffff768fa1p-1) 9 x 0.1 ** 9 = 9/1000000000 10 9999999999/10000000000 0.9999999999000000 0x1.ffffffff2419p-1(0x1.ffffffff2419p-1) 9 x 0.1 ** 10 = 9/10000000000 11 99999999999/100000000000 0.9999999999900000 0x1.ffffffffea028p-1(0x1.ffffffffea028p-1) 9 x 0.1 ** 11 = 9/100000000000 12 999999999999/1000000000000 0.9999999999990000 0x1.fffffffffdcd1p-1(0x1.fffffffffdcd1p-1) 9 x 0.1 ** 12 = 9/1000000000000 13 9999999999999/10000000000000 0.9999999999999000 0x1.ffffffffffc7bp-1(0x1.ffffffffffc7bp-1) 9 x 0.1 ** 13 = 9/10000000000000 14 99999999999999/100000000000000 0.9999999999999900 0x1.fffffffffffa6p-1(0x1.fffffffffffa6p-1) 9 x 0.1 ** 14 = 9/100000000000000 15 999999999999999/1000000000000000 0.9999999999999990 0x1.ffffffffffff7p-1(0x1.ffffffffffff7p-1) 9 x 0.1 ** 15 = 9/1000000000000000 16 9999999999999999/10000000000000000 1.0000000000000000 0x1p+0(0x1.fffffffffffffp-1) 9 x 0.1 ** 16 = 9/10000000000000000 17 99999999999999999/100000000000000000 1.0000000000000000 0x1p+0(0x1p+0) 9 x 0.1 ** 17 = 9/100000000000000000 18 999999999999999999/1000000000000000000 1.0000000000000000 0x1p+0(0x1p+0) 9 x 0.1 ** 18 = 9/1000000000000000000 19 9999999999999999999/10000000000000000000 1.0000000000000000 0x1p+0(0x1p+0) 9 x 0.1 ** 19 = 9/10000000000000000000 結果とお勧めの指定の意味はこれから勉強してみます。 ありがとうございます。 坂元史明 On 2014/04/23 17:23, "EGUCHI Osamu" wrote: >えぐち@エスアンドイーです > >sprintf の %a フォーマットで浮動小数点数のビットパターンを見てみると、 >発見があるかもしれません。 > > output = sprintf("%18.16f %a(%a)", c, c, eval("0." + "9" * i)) > >こんな感じ。 > > えぐち > >2014年4月23日 16:50 Fumiaki Sakamoto : >> ありがとうございます。 >> 早速行ってみます。 >> >> On 2014/04/23 16:42, "Tetsuo Sakaguchi" wrote: >>>In message >>>2014-04-23T15:17+0900, >>> Fumiaki Sakamoto wrote: >>>> Rationalを使っても、0.1という形で10分の1を表現しても私の方法では結果は同じで >>>> した。 >>> >>>a に Rational のインスタンスをいれても他に Float な値があると計算する際に >>>Float に変換されて、2進の浮動小数点数計算になるので、十進の 0.1 は >>>2進化される際に近似値になってしまうと思います。その辺りが >>>きしもとさんの「中途半端に」という指摘なんだと思います。 >>> >>>Rational で計算させたいのなら、b とか c に代入している 9.0 とか 0.0 も >>>Rational か整数にしないと。。。 >>> >>>> もともと、0.999...という循環小数が >>>> 0.999...= 9 x (1/10)**1 + 9 x (1/10)**2 + 9 x (1/10)**3 + ・・・+ 9 x >>>> (1/10)**n >>>> で表現され、n=∞の時に1に等しくなるというところを出典に試しに計算させたもので >>>> す。 >>>> >>>> On 2014/04/23 13:33, "KISHIMOTO, Makoto" >>>>wrote: >>>> >>>> >きしもとです >>>> > >>>> >> require 'rational' >>>> >> a = 0.1 あるいは a = Rational(1, 10) >>>> > >>>> >この、中途半端に有理数を使って(使おうとして)いるのは何でしょうか?