Dev.to WebDev ๐Ÿ›  Dev ๐Ÿ‘ 0 ๐Ÿ“– 5 min read

Where the Penny Lands: The Order of Rounding Inside the OnePassApps Invoice Maker

I work on OnePassApps, the team behind app.onepassapps.com. This is our own app, and every number below came out of the live Invoice Maker panel in one signed-out Chrome session on 7 November 2026, by typing the values i

I work on OnePassApps, the team behind app.onepassapps.com. This is our own app, and every number below came out of the live Invoice Maker panel in one signed-out Chrome session on 7 November 2026, by typing the values in and reading the preview back.

Why this post exists

On 6 November we published what the Invoice Maker preview shows, and we wrote at the end of it: "I am reporting what the header showed, not making a claim about the order the rounding happens in." That was the honest limit of that measurement, and this post is the answer to it, because the app's own panel tells you there IS an order:

Amounts are worked out in GBPโ€™s smallest unit and rounded half-up on each line.

Half-up and per-line are both there, and both matter, but neither of them tells you the two things that actually decide the number: whether the quantity multiplies before the rounding or after it, and whether the subtotal adds up the rounded lines or the raw ones. Those can differ by a penny, and nobody reading a preview can see which one happened.

So I built an invoice with five lines chosen so that the possible rules give different answers.

The five lines

Each line was typed into the live form with real key events and read back out of the preview table afterwards.

Description Qty Unit price Tax Amount printed
Half penny once 1 ยฃ0.005 0% ยฃ0.01
Half penny twice 1 ยฃ0.005 0% ยฃ0.01
Three half pennies 3 ยฃ0.005 0% ยฃ0.02
Tax on a penny 1 ยฃ0.01 50% ยฃ0.01
Tax on three 1 ยฃ0.03 50% ยฃ0.03

The preview then printed: Subtotal ยฃ0.08, a tax row reading "Tax at 50% on ยฃ0.04" for ยฃ0.02, and a final row of Total due (GBP) ยฃ0.10. The header above the document read "A4 ยท ยฃ0.10".

What the five lines decide

The product is rounded once, at the line, not once per unit. The third line is the one that separates the two rules. Three units at ยฃ0.005 is ยฃ0.015. The line printed ยฃ0.02, which is ยฃ0.015 rounded once. If the app had rounded the unit price first and then multiplied, it would have printed ยฃ0.03, because ยฃ0.005 would have become ยฃ0.01 three times over. The panel keeps the unit price at three decimals in the UNIT PRICE column and the rounding happens once, on the line total.

A tie goes up, and that rules out two alternatives. The first line is ยฃ0.005, exactly half a penny, and it printed ยฃ0.01. Half-up sends a tie to the next penny. Rounding to even - the rule banks call half-even - would send half a penny DOWN to zero, because zero is the even number, and truncating would also print ยฃ0.00. The app printed ยฃ0.01, so it is half-up in the arithmetic sense, and not truncation.

The subtotal adds up lines that were already rounded. The five printed amounts are ยฃ0.01, ยฃ0.01, ยฃ0.02, ยฃ0.01 and ยฃ0.03, and they add up to exactly the ยฃ0.08 the preview printed as Subtotal. The unrounded products add up to ยฃ0.065, which would have come to ยฃ0.07 - or ยฃ0.06, depending on how the sum is carried in binary floating point - if the app had added the raw numbers and rounded the total once. It printed ยฃ0.08, so the subtotal is a sum of already-rounded lines. The clearest place to see it is the first two lines: two lines priced at ยฃ0.005 each print ยฃ0.01 each, so the pair costs ยฃ0.02, not ยฃ0.01.

The tax base is built from those same rounded line amounts. The two 50% lines carry ยฃ0.01 and ยฃ0.03, the tax row reads "Tax at 50% on ยฃ0.04", and ยฃ0.04 is what those two rounded lines add up to. So the tax is worked out on the rounded lines rather than on the raw products. The panel says as much in its own words:

Prices exclude tax. Tax is worked out from the rate you enter on each line.

and

You set every tax rate. Invoice Maker does not check them and gives no tax or legal advice.

One thing this run cannot show is how the tax line itself is rounded, because 50% of ยฃ0.04 lands exactly on ยฃ0.02 with nothing left over. I did not construct a rate where the tax lands on half a penny, so I am not claiming an answer for that.

The total is the two rounded pieces added together: ยฃ0.08 plus ยฃ0.02 is the ยฃ0.10 that both the Total due (GBP) row and the "A4 ยท ยฃ0.10" header show.

The precision lives in the line, not in the total

One detail worth seeing for yourself: the preview keeps the unit price exactly as typed, at three decimals, so the third row reads ยฃ0.005 in the UNIT PRICE column while its AMOUNT column reads ยฃ0.02. The precision you entered is preserved on the line and is not carried into the money.

The field caps are in the markup

These are the maxlength attributes on the live form fields, read from the DOM - I did not type to the ceiling, so these are the caps the app sets, not limits I hit:

  • Description: 500 characters. Qty: 12. Unit price: 22. Tax %: 8.
  • Name or business: 200. Client name: 200. Address: 1,000. Email: 200. Tax or company number: 100.
  • Invoice number: 60. Days after issue: 3. Payment details: 2,000. Notes: 4,000.

The Qty and Tax % caps are wide enough for anything real, but "Days after issue" allows three characters, so 999 is the largest number of days you can type into it. The line counter read "1 of 100" on a fresh panel and "6 of 100" once six lines had been added.

What I did not test

I left the currency on GBP, so this is GBPโ€™s smallest unit and nothing else - I did not check what the panel says or does for a currency whose smallest unit is not a hundredth. I did not test a tax rate whose own amount lands on half a penny. I did not touch the discount control, the Quote document type, the other paper sizes, the JSON draft import and export, or printing to a PDF. One build, one signed-out browser session, 7 November 2026 - and I can only read what the preview printed, so what I am claiming is that these readings rule out the rules that would have printed a different number, not a description of the code behind them.

If you want the shape of the tool rather than the arithmetic, our earlier post covers the line items, the tax rates and the totals: https://dev.to/onepassapps/create-an-invoice-in-your-browser-line-items-tax-rates-and-the-total-the-preview-shows-300

Try the Invoice Maker: https://app.onepassapps.com/apps/invoice-maker?utm_source=devto&utm_medium=post&utm_campaign=invoice-rounding&utm_content=invoice-maker-link

The guide, with the limits it states: https://app.onepassapps.com/guides/invoice-maker?utm_source=devto&utm_medium=post&utm_campaign=invoice-rounding&utm_content=guides-link

I work on OnePassApps, so this is our own app and our own measurement. If your copy of the panel says something else, believe your screen - the app moves faster than this post does.

๐Ÿ“ฐ Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes โ€” full credit and traffic to the original publisher.