In JavaScript, 0.1 + 0.2 is 0.30000000000000004. For most numbers that doesn't matter. For money it does: a total that's off by a fraction of a cent eventually shows up as a wrong balance. This piece explains why it happens and three ways to avoid it.
Computers store most decimal numbers in binary floating point, which can't represent 0.1 exactly, the same way you can't write one third exactly in decimal.
What goes wrong
0.1 + 0.2 // 0.30000000000000004
0.1 + 0.2 === 0.3 // false
1.005 * 100 // 100.49999999999999
Math.round(1.005 * 100) / 100 // 1, not 1.01Each error is tiny, but they add up across thousands of transactions, equality checks fail, and rounding can go the wrong way: €1.005 should round to €1.01, not €1.00.
Three safer ways
Store whole cents. Keep amounts as integers: €12.34 becomes 1234. Adding integers is exact, and you only divide by 100 when you show the number.
Use a decimal type. Databases have exact decimal columns, such as NUMERIC in PostgreSQL, and most languages have a decimal library.
Round once, at the end. Keep full precision while you calculate, then format for display.
const cents = [1234, 567, 99]; // €12.34, €5.67, €0.99
const total = cents.reduce((a, b) => a + b, 0); // 1900, exact
new Intl.NumberFormat('en-IE', { style: 'currency', currency: 'EUR' })
.format(total / 100); // "€19.00"What it costs
Cents need care with currencies that use a different number of decimal places, and with interest, which creates fractions of a cent you have to round on purpose. The calculators on this site use plain floating point, because they estimate over years and only show whole euros. An app that keeps real balances shouldn't.
What's next
A future piece looks at how bank CSV exports format amounts, which is where many of these bugs start.