ENGINEERING NOTE 29 / 50 · CARD
Avoid floating-point drift in card fee calculations
Represent money with explicit currency and precision. Binary floating point is a poor default for accumulating financial amounts.
Published by OPEN RAMBO. The engineering patterns and pseudocode illustrate designs, not a documented product API. Numerical examples are illustrative.
Choose a canonical representation
For fixed currency precision, integer minor units simplify equality and totals. Other assets may need a decimal representation with a documented scale. Do not assume every currency has two decimal places or every upstream API uses the same unit.
Round at defined boundaries
Specify when percentage fees are rounded and which rounding rule applies. Rounding each line can differ from rounding the final total. Keep the accepted pricing version with the operation so a later fee change does not alter historical reconciliation.
Test boundaries
Use zero, the smallest supported amount, values around a rounding boundary and the maximum supported amount. Serialize integers safely across languages. A display formatted to two decimals must not hide an underlying arithmetic mismatch.
Illustrative implementation
amount_minor = 1234
fixed_fee_minor = 50
net_minor = amount_minor - fixed_fee_minor
assert net_minor == 1184Acceptance check
Compare line-level totals with ledger totals using exact arithmetic. Include currencies with different precision in test fixtures.