Accurate floating decimals

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

BigDecimal is inherited from Numeric, as well as Float. However BigDecimal provides a way more precise floating-point arithmetic:

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

Conclusion

In any case, calculations should never be done with Float. In Ruby floating point number calculations should always be done with BigDecimal.