dogwood008の開発メモ!

最近のマイブームは機械学習, Ruby on Rails。中でも機械学習を使った金融商品の自動取引に興味があります。

【Ruby】正確な小数の計算をするなら、FloatではなくBigDecimalを使う

要旨

[1] pry(main)> 1.1-1.0
=> 0.10000000000000009
[2] pry(main)> require 'bigdecimal'
=> true
[3] pry(main)> BigDecimal('1.1') - 1.0
=> 0.1e0

詳細

1.1 - 1.0 の結果は、Float の場合は誤差が出てしまっている。これは2進数で計算するときに生じる誤差である。なぜ誤差が生じるのかは、下記のサイトでビット列を見ると知ることができるが、詳細は割愛する。

tools.m-bsys.com

BigDecimal を使うと、(精度を指定して)正確な小数計算をさせることができる。

なお、BigDecimalFloat 値を渡してはいけない。 必ず String に変換が必要である。これは BigDecimal オブジェクトが作られる前に誤差が発生することを回避するためである。 Integer ならこの問題は起こらない。

[4] pry(main)> BigDecimal(1.0)
ArgumentError: can't omit precision for a Float.
from (pry):4:in `BigDecimal'

参考

docs.ruby-lang.org

github.com