by Serguey Shinder
In the spring of 2022 the accounts payable system at one of our larger trade customers began rejecting our invoices, roughly one in three, saying the lines did not add up to the total. It was right. On every rejected invoice the lines came to a penny less than the figure at the bottom, and now and then two.
The cause was a feature built that January at the same customer's request. They recharge delivery to their own cost centres, so instead of one line for the pallet charge we spread it across the goods on the order, in proportion to value. Forty pounds across lines worth half, a quarter and a quarter of the order is twenty, ten and ten, and nothing goes wrong. Forty pounds across three lines of equal value is thirteen pounds thirty three and a third each. The code rounded every share to the penny on its own, and the third of a penny vanished three times.
Each line was rounded half up, exactly as our own standard said. Every number on that invoice was individually correct and their sum was wrong, which is the kind of fault that walks through review, because each reviewer checks the part in front of them. Our tests were tidy examples, ninety across three, a hundred across four, chosen by me because they were easy to check by hand and so never left anything over.
What I had not understood is that dividing money is not arithmetic. A penny cannot be split, so when a sum does not divide evenly somebody has to receive what is left, and a program that never decides who has decided anyway, usually by dropping it on the floor and occasionally, when the rounding goes the other way, by inventing one.
The routine now fixes the total first and treats it as untouchable. Shares are calculated and rounded down to the penny, and the pennies left over are handed out one at a time to the lines with the largest fractional parts, ties broken by line order so the same invoice always comes out the same way. The parts add up to the whole by construction rather than by luck. The test that matters is no longer an example. It generates thousands of random totals and weightings and asserts one thing only, that the lines sum to the total.
We found the same shape twice more, in a discount spread across order lines and in a supplier rebate divided between branches, which had drifted by a few pounds a month for years into a rounding account nobody questioned.
Whenever I see a division anywhere near money now, I look for the line that says where the remainder goes. If I cannot find it, the program is still making that decision about somebody's money. It is just doing it where nobody reads.
– Serguey Asael Shinder
Leave a Reply