varunsrin / rusty_money

Money library for Rust
MIT License
85 stars 32 forks source link

Monetary amounts should not keep excess precision #71

Open HaKr opened 2 years ago

HaKr commented 2 years ago

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
brokenthorn commented 1 year ago

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.