Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monetary amounts should not keep excess precision #71

Open
HaKr opened this issue Jun 13, 2022 · 2 comments
Open

Monetary amounts should not keep excess precision #71

HaKr opened this issue Jun 13, 2022 · 2 comments

Comments

@HaKr
Copy link

HaKr commented Jun 13, 2022

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
Copy link
Contributor

brokenthorn commented Dec 27, 2022

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.

@wischi-chr
Copy link

Money doesn't really have a fixed precision, but the cash units have a fixed size.

Let's take gas prices for example, or prices of other products that are sold per weight. It's not uncommon to see 3 or more decimal places for the price per unit mass.

All the calculations are done with maximum precision and only at the last step is the price rounded to the nearest possible unit.

It would be pretty bad design if this library would always round to the smallest unit for all calculations, because it would introduce a lot of issues for the use-cases I mentioned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants