I am developing a financial system and want to have a defined policy for rounding monetary values.
Given the following layers:
- View
- API
- Entity Model
- Persistence
If I am passing a monetary value through these layers, and maybe using it in calculations in the model, at what layer (if any) should I be applying my "default" rounding policy?
My instinct is in the View, as rounding the number is a "view" concern, like formatting a date. I also feel it could cause problems if my entities round money values as this could affect the accuracy of calculations. However if my API specifies a value as "money" it would seem incorrect to provide consumers with values that are not rounded e.g. £109.563393939939 rather than £109.56.
I have been unable to find any "best practice" around this.
Aside from this old question: https://stackoverflow.com/a/3840903/470183
Best Answer
Monetary values in general do not use floating point (always approximation errors!), but fixed point, as
BigDecimal
in java,DECIMAL
in SQL. For currencies you then have a defined precision (2 decimals for instance).Now national regulations prescribe the precision of some calculations, like taxes with a precision of 6 (Europe). These kind of precisions should be part of the business logic, giving rounded exact values of calculations.
Higher layers like for the views are then given a fixed precision, with already rounded values from calculations.
In this way end-point summing (outside the system, say in exported Excel) of exported values will give no deviations from in-system sums.