Nowadays multiplying or adding BigDecimal
with Float
results in BigDecimal. This is the case for at least Ruby >= 2.3.
Ruby comes with a class
BigDecimal
Show archive.org snapshot
which you can use for arbitrary precision arithmetic. You should use BigDecimal
instead of Float
whenever you care about rounding errors, e.g. whenever you are dealing with money.
You should remember these two rules when working with BigDecimal
values:
- When you add or multiply a
BigDecimal
with anotherBigDecimal
, the result will be a newBigDecimal
with sufficient precision to represent the result. No rounding or clipping should occur in that operation. - When you add or multiply a
BigDecimal
with aFloat
, the result will be aFloat
. That means you just transitioned back into the land of random rounding errors.
Don't screw up your clean BigDecimal
values by thoughtlessly multiplying them with a Float
. For instance, this is a stupid idea:
VAT_RATE = 1.19
net = BigDecimal('12.3413')
gross = net * VAT_RATE # oops, gross is now a Float
Do this instead:
VAT_RATE = BigDecimal('1.19')
net = BigDecimal('12.3413')
gross = net * VAT_RATE # gross is now a BigDecimal
ActiveRecord models represent MySQL's DECIMAL
columns as BigDecimal
attributes. Keep in mind that values assigned to such attributes might be clipped or rounded when the record is saved to the database.