Calculations in the field of floating point numbers are imprecise to some degree. The reason is the numbers internal representation/storage (binary/ finite Bytes). Each language has to deal with it. Of course Ruby is no exception.\
Float is imprecise
An example for imprecise calculation with Float numbers:
0.1 + 0.2 # => 0.30000000000000004
If the domain for instance is about money, this is certainly an issue. That is why banks do not calculate with Float numbers.
BigDecimal is precise
result = BigDecimal.new(0.1, 15) + BigDecimal.new(0.2, 15) # => #<BigDecimal:21b6848,'0.3E0',9(18)> result.to_s('F') # => "0.3"
BigDecimal objects can be printed as a String in a floating decimal notation with the argument F:
number = BigDecimal.new(0.1, 5) number.to_s # => "0.1E0" number.to_s('F') # => "0.1"
Further notations are available. For instance the output can be formatted into blocks with a separating whitespace. Positive numbers can printed accordingly:
number = BigDecimal.new(12.3456789, 15) number.to_s('3F') # => "12.345 678 9" number.to_s('+4F') # => "+12.3456 789"
Hence BigDecimal provides rudimentary output formatting.
Integer is precise
It also may make sense to cast the values into their smallest possible unit and calculate with Integer numbers in some cases. Merely the result would have to be casted back again into a floating point representation:
number = 20 + 10 # => 30 number / 100.0 # => 0.3
In any case, calculations should never be done with Float. In Ruby floating point number calculations should always be done with BigDecimal.