Currency Precision Review Workflow
Represent money in minor units or decimal types, avoid floating point, define rounding to the currency, and centralize formatting and arithmetic.
Objective
Prevent rounding and precision bugs by reviewing how monetary values are stored and computed.
Environment
- Access to the data model and financial code paths
- Test cases with rounding boundaries
Steps
1. Check that money is stored
Check that money is stored in integer minor units or a decimal type, never float.
Expected state: Values are exact.
2. Define rounding rules per currency
Define rounding rules per currency and operation.
Expected state: Rounding is deterministic and documented.
3. Centralize arithmetic and formatting in one
Centralize arithmetic and formatting in one module.
Expected state: Tax and total logic is consistent.
4. Test rounding boundaries, zero-decimal currencies,
Test rounding boundaries, zero-decimal currencies, and large amounts.
Expected state: Edge cases behave correctly.
Decision points
Integer minor units or decimal?
- Integer minor units
- Decimal type
Integer minor units avoid type pitfalls and serialize cleanly; decimal is acceptable where the database supports it well.
Round per line or on the total?
- Defined and consistent
- Whatever is convenient
Pick one and document it; mixed strategies create tax discrepancies.
Expected outcome
Monetary values stored exactly, rounded by documented rules, with centralized arithmetic and verified edge cases.
Verification
Confirm tests show no floating-point drift, correct handling of zero-decimal currencies, and documented rounding on totals and tax.
Cleanup
Record the representation and rounding policy in the engineering guide.
Overview
Prevent rounding and precision bugs by reviewing how monetary values are stored and computed. Confirm tests show no floating-point drift, correct handling of zero-decimal currencies, and documented rounding on totals and tax.
Steps
- Check that money is stored in integer minor units or a decimal type, never float. Expected state: Values are exact.
- Define rounding rules per currency and operation. Expected state: Rounding is deterministic and documented.
- Centralize arithmetic and formatting in one module. Expected state: Tax and total logic is consistent.
- Test rounding boundaries, zero-decimal currencies, and large amounts. Expected state: Edge cases behave correctly.
// store integer minor units
const price = 1999; // $19.99
const total = price * qty; // integer math
const display = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(total / 100);
Verification
- Monetary values stored exactly, rounded by documented rules, with centralized arithmetic and verified edge cases.
Decision points
- Integer minor units or decimal? Options: Integer minor units; Decimal type. Recommended: Integer minor units avoid type pitfalls and serialize cleanly; decimal is acceptable where the database supports it well.
- Round per line or on the total? Options: Defined and consistent; Whatever is convenient. Recommended: Pick one and document it; mixed strategies create tax discrepancies.