Skip to content
AspirecoStart
All answers

Custom software

Why should business software never store money as a float?

The short answer

Because a float cannot store most decimal amounts exactly: 0.1 is already slightly wrong before any arithmetic runs. Across a job, those tiny errors become invoices whose lines do not match their totals and ledger entries that do not balance. Store money as an integer number of cents, and round once.

Updated

The literal 0.1 is not 0.1

A double-precision float stores a number as an integer times a power of two, so only fractions with a power-of-two denominator are exact. One tenth is not, which is why 0.1 + 0.2 prints 0.30000000000000004. That is correct behaviour for measurement, where the last bit is noise. In money, the last bit is a cent somebody is owed.

Where it bites

Not in the obvious case. It bites when an estimate becomes a job, the job collects bills, timesheets and change orders, and each line is rounded along the way: the sum of the rounded lines stops matching the rounded sum. In double-entry books that is not cosmetic — an entry is only valid when its debits equal its credits.

The fix

Store amounts as exact decimals in the database and as integer cents in calculations, and round once, when the amount becomes real — posted, printed or charged. Contractor OS, our own platform, has no floating-point money values anywhere, and every financial document posts a balanced journal entry.

The full reasoning, with worked examples, is in Money does not belong in a float.

Asked next

How can we tell if our system stores money as a float?

Search the database schema for float, real and double precision columns that hold amounts. Then check what your driver returns for numeric columns — some hand back a JavaScript number, which has already converted the exact value. Finally, count the rounding steps in one invoice's code path: more than one per amount is where the cent goes.

Should tax rates and quantities be stored like money?

No. A tax rate, a markup or a labour hour is a ratio or a measure, not a count of cents. In Contractor OS they are carried at six decimals, and a line's amount comes down to cents once, at the end.