Saturday, May 26, 2007

Rounding

Issues associated with rounding are probably among the most frustrating ones I've had to deal with building financial systems.

Rounding problems have 4 main root causes.
1. Using IEEE floating point representation to store and operate on quantity and money amounts.
2. Rounding too early or too late when performing financial calculations
3. Not persisting the data that was input or viewed by end user and relying being able to derive it from other persisted data.
4. Not capturing remainder when allocating/splitting quantity or money amounts

The best advice I can give around usage of floats and doubles is don't use them in your financial system. C# and Python have good native support for Decimal, Java and Ruby have BigDecimal, even for C++ there are variety of public domain decimal classes that one can find.

Having a decimal in your toolbox is good, and it'll solve problem #1. But don't stop there, when dealing with money amounts you need the Money class that will keep currency together with the amount, and embed rounding rules in this class. Another useful class for your toolbox is quantity, which also encapsulates the unit.

These simple encapsulations will go a long way to making sure that your system can produce accurate settlement and P&L numbers without getting bogged down by tangled web of custom rounding code.