QA@IT
«質問へ戻る

重複を削除

1138
本文
 ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
 "1.0"
 
-$ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
-ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
-"1.0"
-
 ~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
 ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-darwin11.4.2]
 "0.9999999999999999"

Rubyで0.1を10回足して 1.0 になっていたのは間違い?

手元にあるいくつかのバージョンのRubyで、0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 を計算したところ、1.8系では 1.0 、1.9系では 0.9999999999999999 となりました。

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
rubinius 1.2.0 (1.8.7 release 2010-12-21 JI) [x86_64-apple-darwin10.6.0]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.6 (2010-09-02 patchlevel 420) [i686-darwin11.4.2]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-darwin11.4.2]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 2.0.0dev (2012-10-12 trunk 37163) [x86_64-darwin11.4.2]
"0.9999999999999999"

2進法で0.1が循環小数になるため、浮動小数点の精度によって相応の誤差が出るというのが私の理解です。

では逆に、Ruby 1.8系では何が起こっていたのでしょうか? 浮動小数点演算の標準規格、IEEE 754 : Wikipedia からすると、どちらの結果が正しい、というようなことがあるのでしょうか? なぜ 1.8 と 1.9 で動作が変わったのでしょうか?

手元にあるいくつかのバージョンのRubyで、`0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1` を計算したところ、1.8系では 1.0 、1.9系では 0.9999999999999999 となりました。

~~~bash
~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
rubinius 1.2.0 (1.8.7 release 2010-12-21 JI) [x86_64-apple-darwin10.6.0]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.6 (2010-09-02 patchlevel 420) [i686-darwin11.4.2]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-darwin11.4.2]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 2.0.0dev (2012-10-12 trunk 37163) [x86_64-darwin11.4.2]
"0.9999999999999999"
~~~

2進法で0.1が循環小数になるため、浮動小数点の精度によって相応の誤差が出るというのが私の理解です。

では逆に、Ruby 1.8系では何が起こっていたのでしょうか? 浮動小数点演算の標準規格、[IEEE 754 : Wikipedia](http://ja.wikipedia.org/wiki/IEEE_754) からすると、どちらの結果が正しい、というようなことがあるのでしょうか? なぜ 1.8 と 1.9 で動作が変わったのでしょうか?

質問を投稿

Rubyで0.1を10回足して 1.0 になっていたのは間違い?

手元にあるいくつかのバージョンのRubyで、0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1 を計算したところ、1.8系では 1.0 、1.9系では 0.9999999999999999 となりました。

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
rubinius 1.2.0 (1.8.7 release 2010-12-21 JI) [x86_64-apple-darwin10.6.0]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.6 (2010-09-02 patchlevel 420) [i686-darwin11.4.2]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
"1.0"

$ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-darwin11.4.2]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 2.0.0dev (2012-10-12 trunk 37163) [x86_64-darwin11.4.2]
"0.9999999999999999"

2進法で0.1が循環小数になるため、浮動小数点の精度によって相応の誤差が出るというのが私の理解です。

では逆に、Ruby 1.8系では何が起こっていたのでしょうか? 浮動小数点演算の標準規格、IEEE 754 : Wikipedia からすると、どちらの結果が正しい、というようなことがあるのでしょうか? なぜ 1.8 と 1.9 で動作が変わったのでしょうか?

手元にあるいくつかのバージョンのRubyで、`0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1` を計算したところ、1.8系では 1.0 、1.9系では 0.9999999999999999 となりました。

~~~bash
~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
rubinius 1.2.0 (1.8.7 release 2010-12-21 JI) [x86_64-apple-darwin10.6.0]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.6 (2010-09-02 patchlevel 420) [i686-darwin11.4.2]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
"1.0"

$ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.4.0]
"1.0"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-darwin11.4.2]
"0.9999999999999999"

~ ruby -ve 'p eval(Array.new(10, "0.1").join("+")).inspect'
ruby 2.0.0dev (2012-10-12 trunk 37163) [x86_64-darwin11.4.2]
"0.9999999999999999"
~~~

2進法で0.1が循環小数になるため、浮動小数点の精度によって相応の誤差が出るというのが私の理解です。

では逆に、Ruby 1.8系では何が起こっていたのでしょうか? 浮動小数点演算の標準規格、[IEEE 754 : Wikipedia](http://ja.wikipedia.org/wiki/IEEE_754) からすると、どちらの結果が正しい、というようなことがあるのでしょうか? なぜ 1.8 と 1.9 で動作が変わったのでしょうか?