Split-the-bill math that doesn't lose cents
The most embarrassing POS bug in the world: a table of three asks to split a AED 100 bill evenly, and the system replies "AED 33.33 each, total AED 99.99". Someone has paid the missing cent. Sometimes nobody notices, sometimes the chef covers it, sometimes the customer argues. The fix is one line of code, and most POS systems still get it wrong.
Why the naive split breaks
Most systems compute:
per_person = round(total / n, 2) total_after_split = per_person * n
For total = 100, n = 3, per_person = 33.33 and the sum is 99.99. The cent is gone. Multiply by 200 covers a day and you've "lost" AED 2 of "we'll absorb it" cash. Across a year, the cashier is short, the books are off, and nobody can explain why.
The one-line fix
Force the last person to absorb the remainder. Compute the sum in integer cents (so there's no floating-point noise), then put the leftover on the last split:
total_cents = round(total * 100) base_cents = total_cents // n remainder = total_cents - base_cents * n # 1 cent here splits = [base_cents] * n splits[-1] += remainder # last person pays 33.34
For total = 100, n = 3: base = 3333, remainder = 1, so the splits are [3333, 3333, 3334] cents = [33.33, 33.33, 33.34] dirhams. The sum is exactly 100.00.
Same idea for any divisor: AED 100 / 7 → 14.29, 14.29, 14.29, 14.29, 14.28, 14.28, 14.28. The remainder is 1 cent; spread it across the last few splits, or just give it to the last person — either is fine, as long as the sum is exact.
Item-based splits need the same care
When guests split by item ("I had the truffle pasta, she had the salad"), the per-item rounding adds up differently. The fix is the same in spirit: assign each item to a payer, sum the assigned items, then adjust the last payer's share by the cent remainder. We also recommend not allowing a payer to be assigned an item twice — duplicate assignment is the other classic split-bill bug.
How table sessions help
A table session is one logical bill that lives from the first order to the last. Orders accumulate, splits accumulate, and the session only closes when all splits are paid. This is where the "every round goes on the same tab" pattern lives, and it makes splits auditable: every payment writes a transaction with a session id, the cashier's id and a timestamp.
What to ask any POS vendor
Three questions that flush out the bugs:
- "If I split AED 100 by 3, do the splits sum to exactly 100.00?"
- "If a guest is assigned the same item in two splits, do you reject it?"
- "What happens if one of the splits is paid and another is then voided — does the session re-open cleanly?"
If the answer to the first one is "almost, but with rounding" — keep looking.