要旨
[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進数で計算するときに生じる誤差である。なぜ誤差が生じるのかは、下記のサイトでビット列を見ると知ることができるが、詳細は割愛する。
BigDecimal
を使うと、(精度を指定して)正確な小数計算をさせることができる。
なお、BigDecimal
に Float
値を渡してはいけない。 必ず String
に変換が必要である。これは BigDecimal
オブジェクトが作られる前に誤差が発生することを回避するためである。 Integer
ならこの問題は起こらない。
[4] pry(main)> BigDecimal(1.0) ArgumentError: can't omit precision for a Float. from (pry):4:in `BigDecimal'