Monetary amounts should not keep excess precision
HaKr opened this issue · comments
When handling monetary amounts, the precision should be that of the minor unit instead of mathematical correct fractions. Current implementation seems to maintain the mathematical fraction
let amount: Money<Currency> = Money::from_major(100, iso::EUR) / 3;
assert_eq!(amount.to_string(), "€33,33"); // that is what I expect
let triple_amount: Money<Currency> = amount * 3;
assert_eq!(triple_amount.to_string(), "€99,99"); // assert fail because expected is "€100,00", but 3 x €33,33 = €99,99
But this is a rounding error, isn't it? It's present even in the most sophisticated accounting applications.
The operations otherwise seems correct to me. Even the last one. 33,33 * 3 = 99,99 no matter the currency.
This is happening because money has fixed precision and dividing 100 by 3 creates an approximate value using rounding to the money's minor units.