Most bugs in money software are not dramatic. They are a penny that appears from nowhere, or a balance that refuses to reach zero no matter how carefully everyone pays. Small, quiet, and corrosive to trust.
DueCircle avoids that class of problem by never storing money as a decimal in the first place. Every amount is a whole number of the smallest unit a currency has. This is a behind-the-scenes decision, but it is the reason your splits always reconcile, so it is worth explaining plainly.
How decimals quietly lose and invent money
Computers store fractional numbers in binary floating point. Binary cannot represent most decimal fractions exactly, in the same way that base ten cannot write one third without an endless run of threes. The result is a value that is very close, but not equal, to what you typed.
The textbook demonstration is that 0.1 plus 0.2 does not equal 0.3 on most systems. It equals 0.30000000000000004. That surplus is tiny, but money is not a place for tiny surpluses. Multiply thousands of transactions by a fraction of a cent and the ledger starts to drift.
Division makes it worse because real money cannot always be divided cleanly. Split 100.00 dollars three ways and each share is 33.333… dollars. Round each to 33.33 and the three shares total 99.99. One cent has simply vanished. Round up instead and you invent a cent that nobody actually owes.
What minor units and integer money mean
A minor unit is the smallest amount a currency officially recognises. For the US dollar or the euro it is the cent, one hundredth of the major unit. Rather than storing 12.34 dollars, DueCircle stores the integer 1234, meaning 1234 cents.
Integers are exact. There is no nearest representable value and no rounding error hiding in the last decimal place, because there are no decimals. Addition, subtraction and comparison are all exact by construction, which is precisely what a ledger requires.
The number of minor units per major unit is not universal, so we carry it per currency rather than assuming two decimal places. The Japanese yen has no minor unit at all, so amounts are whole yen. The Kuwaiti dinar divides into 1000 fils, so it needs three decimal places. Most currencies use two. Storing integers plus a known scale lets us format each currency correctly and still compute exactly.
- 12.34 US dollars is stored as 1234 (cents, scale of 2)
- 500 Japanese yen is stored as 500 (whole yen, scale of 0)
- 1.250 Kuwaiti dinars is stored as 1250 (fils, scale of 3)
Largest-remainder allocation, worked through
Exact storage solves representation, but division still has to land somewhere. If 100.00 dollars will not divide evenly by three, someone has to carry the extra unit. The question is who, and the answer needs to be defensible.
DueCircle uses the largest-remainder method. First we work in minor units, so the total is 10000 cents. We give each person the whole-number floor of their share: 10000 divided by 3 is 3333 cents each, using 9999 cents. That leaves a remainder of one cent to place.
We then rank the participants by the size of the fractional part we discarded when flooring. Here every person had the same remainder of one third, so we break the tie by a stable order, and the single leftover cent goes to the first person. Their share becomes 3334 cents. The allocation is now 33.34, 33.33 and 33.33, which sums to exactly 100.00.
The method generalises to any split type. Percentages, shares, exact amounts and custom weights all reduce to the same step: compute floors in minor units, then distribute the leftover units to the largest remainders until the total is met. The shares always sum to the original amount because we never round the total; we only decide who absorbs the indivisible remainder.
Why we name who carries the leftover cent
It would be easy to hide the remainder and simply show rounded figures. We do the opposite. When one person carries an extra cent, the split makes that visible rather than smoothing it away.
Naming the carrier does two things. It keeps the arithmetic honest, because the displayed shares genuinely add up to the total with nothing swept under the rug. And it keeps the split fair over time, because the method is deterministic and the burden is distributed by a consistent rule rather than by chance.
A single cent rarely matters on one bill. Across a shared flat with dozens of recurring expenses a month, a rule that always favoured the same person would slowly compound. Making the carrier explicit means anyone can see the rule is being applied evenly.
How this makes every balance auditable
When every amount is an exact integer, a balance is just a sum of integers. There is no accumulated floating-point drift to explain, so you can add up the contributions and the shares by hand and get the same answer the app does.
This is what makes the settle-up plan trustworthy. DueCircle works out the fewest payments that clear every balance, and because the underlying figures are exact, the plan resolves the group to precisely zero. Not approximately zero, not zero give or take a cent, but zero.
The same property carries through the rest of the product. Recurring bill reminders, month-on-month budgets and per-group roles all read from the same integer ledger, so a figure means the same thing everywhere it appears. Nothing is being connected to your bank and no money is being held; this is bookkeeping done accurately, which is the part people actually want to get right.
That is the whole argument for expense splitting accuracy. Store money as whole numbers, allocate remainders by a fair and stated rule, and show your working. The reward is a ledger that reconciles every time, and a group that never has to argue about a missing penny.
Published 14 July 2026.