Home / Blog / Engineering
EngineeringSplit bill rounding: why your app and spreadsheet differ by a cent
A $100.00 bill split three ways leaves one cent that a spreadsheet drops and Dimesum gives to one person, chosen by a fixed hash of the bill. Here is the worked table, the rule we replaced, and the two currency mistakes only a sheet can make.
Your spreadsheet says $66.66 and the app says $66.67. That one cent is split bill rounding, and it is the commonest message we get from someone who checked Dimesum against Excel. The short answer: the sheet rounds each share on its own and loses the leftover cent, while Dimesum hands that cent to one person, chosen by a fixed hash of the bill, so the shares always add back to the total.
The problem, the cause and the fix, in three sentences you can lift. A $100.00 bill split three ways cannot be paid in three equal amounts, so somebody carries $33.34. A spreadsheet that rounds each cell shows $33.33 three times and quietly drops a cent, while Dimesum keeps the cent and decides who carries it by the bill's own hash. The two will agree on every bill that divides evenly and differ by at most one cent per person on every bill that does not.
The symptom: a cent that one side has and the other does not
The report usually arrives the same way. Someone exports a month of bills, rebuilds the balances in a sheet, and finds a few cents of disagreement. Nothing is missing on either side by more than a cent per bill, and yet nobody can make the two match.
We wrote about the four reasons a group balance looks wrong in why shared balances never add up. This post takes the first of them, the rounded cent, and follows it into a spreadsheet, because that is where a careful person goes to check us. It also covers the two places a sheet goes wrong that an app cannot: adding two currencies in one column, and giving the yen two decimal places it does not have.
A $100.00 bill, three ways, in a sheet and in the app
Emma pays $100.00 for dinner. Lucas, Sofia and Emma split it equally. One hundred dollars divided by three is $33.333 and so on forever, which no card can pay.
A sheet can hold that endless number. Type =100/3 into three cells, format them to two decimal places, and each shows $33.33. The SUM cell shows $100.00, because it adds the hidden digits rather than the ones on screen. Now a reader adds the three visible cells with a calculator and gets $99.99.
The careful sheet rounds instead: =ROUND(100/3, 2) in each cell. Now every cell really holds $33.33, the SUM really is $99.99, and the cent has left the sheet. Emma is owed $33.33 by Lucas and $33.33 by Sofia, so the sheet says she gets $66.66 back. Her own share was meant to be $33.33, but she has paid $33.34 of the dinner without anyone writing it down.
| Where it was split | Emma's share | Lucas's share | Sofia's share | Shares add to | Emma is owed |
|---|---|---|---|---|---|
| Dimesum, a bill whose hash gives Emma the odd cent | $33.34 | $33.33 | $33.33 | $100.00 | $66.66 |
| Dimesum, a bill whose hash gives Lucas the odd cent | $33.33 | $33.34 | $33.33 | $100.00 | $66.67 |
Sheet, =100/3 shown to two places | $33.33 | $33.33 | $33.33 | $100.00 in SUM, $99.99 on screen | $66.67 on screen |
Sheet, =ROUND(100/3, 2) | $33.33 | $33.33 | $33.33 | $99.99 | $66.66 |
Every row is arithmetic you can redo.
In the second Dimesum row, Lucas owes $33.34 and Sofia owes $33.33, and $33.34 plus $33.33 is $66.67. In the rounded sheet, $33.33 plus $33.33 is $66.66. Neither is a bug. They are two different rules about one cent, and only one of them keeps the cent on the record.
Why each share is rounded down first
Dimesum splits with the largest remainder method, a rule some parliaments use to turn vote shares into whole seats. Every amount is stored as a whole number of the currency's smallest unit, so $100.00 is 10,000 cents. Each person's exact share is worked out as a fraction, then everyone gets the whole cents below it: 3,333 each, which is 9,999.
That leaves one cent. The leftover cents go out one at a time, to the people whose fractions were cut the most. On an equal split everyone's fraction is the same, a third of a cent, so the rule needs a tie break. That tie break is where our first version went wrong.
The guarantee the method gives is the one a sheet cannot: the shares add back to the total exactly, and no share is more than one cent away from its exact value. The same arithmetic runs for an equal split, a percentage split, weighted shares, every line of an itemised bill and every tax or tip pool on it. Our post on apps to split a bill by item shows it on a four person dinner with a discount.
What we tried first: the oldest member took every odd cent
The first tie break was the obvious one. Members are ordered by when they joined, so ties went to the oldest member. It is deterministic, it is easy to test, and on any single bill nobody could call it unfair.
Over a year it is a surcharge. A flat with three people splits rent, power, the internet and the shopping, and many of those bills leave a cent over. Every one of those cents went to the same person, the one who set the group up. A cent is nothing; a few hundred of them in one direction is a pattern somebody eventually notices in a sheet.
The founder's answer on 21 August 2026 was that a random participant should carry it, so that it evens out over many bills. Random had a catch for us. Dimesum recomputes a bill's split whenever it is edited, and an edit is recorded as a new entry that restates the split, as described in why an edit must restate its split. With a real random draw, an edit that changed only the bill's name would roll again, move the cent to someone else, and post a correction for money that never moved.
The fix: rotate the odd cent by a fixed hash of the bill
So random became pseudo random and fixed. Each bill has its own id, and we hash it with FNV-1a, a small hash that gives the same answer on every machine and every build. The hash picks where in the ordered list the leftover cents start. Same bill, same answer, every time it is computed; across many bills, the starting point lands on each person about equally.
The ordered list is still the largest remainder order, with ties broken oldest member first. The hash only moves where the hand out begins. On an equal three way split, that means each bill picks one of the three people to carry $33.34, and that choice never changes for that bill.
This is why your sheet and the app disagree differently on different bills. On one $100.00 dinner the hash gives Emma the cent and the two agree that she is owed $66.66. On the next, it gives Lucas the cent and the app says $66.67. A sheet with one rule for every row cannot reproduce that, unless it copies the hash.
The cost we accepted
Two bills with identical content may now differ by one cent. Two $100.00 dinners with the same three people can split as $33.34 for Emma on one and $33.34 for Sofia on the other. Two of our own end to end tests compared one bill's shares against another's and broke the day this shipped; they now check the rule's output instead.
We think that is the right trade. The ledger beneath every balance is append only, so a cent that moves without a reason would be written down forever; the design is in the append-only ledger behind every split. A cent that is fixed per bill and spread across people never needs a correction.
A column that adds dollars to euros is not a total
The second difference is bigger than a cent and it is always the sheet's. On a trip, Emma pays a €90 hotel night and a $60 museum ticket, and the sheet has one Amount column with a SUM at the bottom. It says 150. That number has no currency, so it cannot be owed by anybody.
Dimesum keeps every balance per currency and never adds across them. The group sees what is owed in euros and, separately, what is owed in dollars. If the group agrees a rate, Dimesum can show the balances folded into one currency, labelled with the rate, and the debt itself stays in the currency it was spent in.
The bugs that come from doing otherwise are in the money bugs a second currency causes. If a trip is why you are comparing, multi-currency expense splitting apps lines up how other apps hold a second currency.
Folding brings back a rounding of its own. A conversion rounds to whole cents, half away from zero, so balances that summed to zero in yen may sum to one cent over in dollars. We let the lowest member id absorb up to one smallest unit per conversion, and past that the settle plan is refused. A plan that is quietly wrong by $1 is worse than an error, because somebody would pay it.
The yen has no cents, and a sheet gives it two anyway
The third difference shows up on every trip to Japan. The yen has no minor unit: its exponent in the ISO 4217 currency standard is zero, so ¥1 is the smallest amount anyone can pay. A ¥10,000 dinner split three ways in Dimesum comes out as ¥3,334, ¥3,333 and ¥3,333, which adds to ¥10,000.
A sheet formatted for money shows ¥3,333.33 three times, a figure no coin pays. Round it to whole yen and it shows ¥3,333 three times, which adds to ¥9,999. The yen loses one unit the same way the dollar lost a cent.
We broke this ourselves before we fixed it.
The code that reads an amount out of a line of text once turned it into minor units by multiplying by 100, which is right for dollars and euros and wrong for yen: a ¥2,000 taxi became ¥200,000. That was a 100 times error, and no rounding rule could have caught it.
The conversion now reads each currency's exponent from the ISO table, and a figure finer than a currency's smallest unit is refused rather than rounded. Reading amounts out of text has a longer history with us, told in why we deleted our expense parser. How a trip in yen splits without that trouble is in bill splitting apps in Japan.
What else a spreadsheet does to money
Excel stores numbers in binary floating point, and some decimals have no exact binary form. Microsoft's own note on floating point arithmetic in Excel explains why a sum can come out a hair off the figure you expect. Most of the time the display hides it, which is exactly why the cell you see and the value you add can differ.
The rounding functions also have their own rules. Excel's ROUND function and ROUND in Google Sheets round each cell on its own, with no knowledge of the other cells in the split. That is the whole difference: a split needs to round the shares together, so that they still add up to the bill.
Dimesum never stores money as a fraction of a unit. Every amount is a whole number of cents, or of yen, with its currency written next to it, and every split conserves its total exactly. If you would still rather keep the group's money in a sheet, our shared expense tracker template is a fair start, and spreadsheet or app for shared expenses covers where the sheet stops being enough.
How to make your sheet agree with the app
You can reproduce Dimesum's numbers by hand. Work in whole cents. Give each person the whole cents below their exact share, count the cents left over, and hand them out one at a time.
- Convert the bill to cents: $100.00 is 10,000.
- Give each person the floor of their exact share: 3,333 each, 9,999 in all.
- Hand the leftover cent to the person the app shows carrying it, and check the shares add to 10,000.
- Keep one sheet per currency, and never put a SUM across two of them.
Step three is the only one you cannot predict without the bill's hash, so read it off the bill instead. The longer arithmetic for any split, with weights and percentages, is in the split expenses calculator method, and the same check applied to a group's whole history is in how to keep track of who owes who on a trip.
What this still cannot do
It cannot make your sheet and the app agree on every bill without effort. A sheet with one rounding rule per column will differ from Dimesum by a cent on roughly every bill that leaves a remainder, and the person carrying the cent will change from bill to bill. That is the rule working.
It also cannot make a folded total exact. A balance shown in one currency at an agreed rate is advisory, and the settle plan built from it can be one smallest unit out per conversion. The debt that counts stays in the currency it was spent in, which is why settling up a group happens one currency at a time.
Check the sum, not each cell
When the app and your sheet disagree by a cent, add the shares on the bill: if they equal the total, the cent is with one person on purpose. To see which person, open Dimesum, tap the bill, and read the share that is one cent larger than the rest.
Common questions
Why is my split bill app one cent different from Excel?
Because Excel rounds each share on its own and the app rounds the shares together. A $100.00 bill split three ways is $33.33 three times in a rounded sheet, which adds to $99.99. Dimesum gives one person $33.34 so the shares add to $100.00, and a fixed hash of the bill decides who carries that cent.
Who pays the extra cent when a bill splits three ways?
One person, and in Dimesum the bill's own hash decides which one. The shares are worked out by the largest remainder method, and the place where the leftover cents start is rotated by a fixed hash of the bill. The same bill always gives the same answer, and over many bills the cent lands on each person about equally.
Why doesn't Dimesum pick a random person for the odd cent?
Because a real random draw would move the cent every time a bill is edited. Dimesum restates the split on every edit, so a new draw would post a correction for money that never moved. A fixed hash of the bill behaves like a random choice across many bills and gives the same answer every time for one bill.
Can I add balances in two currencies in one spreadsheet column?
No, the total means nothing. €90 and $60 summed to 150 is a number with no currency, so nobody can owe it. Dimesum keeps a balance per currency and never adds across them; a group can see them folded at a rate it agrees, labelled with that rate, while each debt stays in the currency it was spent in.
How does Dimesum split yen when there are no cents?
In whole yen, because the yen's smallest unit is ¥1. A ¥10,000 dinner split three ways is ¥3,334, ¥3,333 and ¥3,333, which adds to ¥10,000. A sheet formatted with two decimals shows ¥3,333.33, which no coin can pay, and rounding each cell to whole yen loses ¥1 the same way a dollar sheet loses a cent.
Popular posts
- Settle up: how to clear group expenses in fewer transfers6 min read
- Why editing a shared expense must restate the split5 min read
- Six money bugs in multi-currency expense splitting6 min read
- Best bill splitting apps: 11 ranked on what lasts14 min read
- The append-only ledger that keeps split-expense balances exact6 min read