The Arithmetic Is The Compliance
A tax figure of ¥423.4 is not a rounding preference. It is an amount of money that does not exist — and the system that produced it is ours.
Raise an invoice in our system for three items priced at ¥1,980, ¥333 and ¥1,255, charge the standard 10% consumption tax, and the tax line reads ¥423.4. The total reads ¥4,657.4. Neither is an amount that can be invoiced, paid or filed, because the yen has no subunit — no sen has circulated since 1953 — and four-tenths of a yen is not a rounding convention but a denomination that does not exist. The database column is decimal(19,3), so it stores 423.400 without complaint.
Nothing in that example is contrived. Those are ordinary shelf prices and the only property that matters is that they are not multiples of ten, which is true of most prices anybody charges. We found it while writing our Japan market page, which is to say we found it while looking for something else.
The mistake is one line of code and it is everywhere
The arithmetic itself is not wrong. Line tax is computed exactly, accumulated across lines, and the document total is rounded once at the end. That is a defensible design. What is wrong is the number it rounds to: two decimal places, written as a literal, twenty times over across the invoice, quotation and point-of-sale paths.
Two is the right answer for most of the world's money and it is not a property of money. It is a property of a currency, and currencies disagree. Some have two places, some have none, and a few have three. We know this — we hold the correct figure for every currency we ship as reference data, and our market pages publish it. A visitor to our own Japan market page was being told, correctly, that the yen has no minor unit, on a page served by a system whose invoice arithmetic had never read that fact.
The uncomfortable part
The reference data was right and the copy derived from it was right. The gap was between knowing the fact and using it. That is a harder class of bug to find than a wrong constant, because everything that displays the fact tests correctly.
Why a zero-decimal currency makes it visible rather than special
It is tempting to file this as a Japanese problem. It is not. In a two-place currency the same defect exists and hides: rounding to two places is correct, so nothing looks wrong, and the code is still asserting a fact about the world rather than reading one. The yen does not create the bug. It develops it, the way a stain shows up under one particular light.
Which is the practical reason to test any accounting system against a currency with no decimals even if you never intend to use one. It is the cheapest available probe for whether precision is data or an assumption, and it takes about two minutes.
And then Japan asks for something harder
Getting the places right would make our figure payable. It would still not make it correct in Japan, because the qualified invoice system does not only say what an invoice must show — it says how the tax may be computed. Fractions may be rounded once for each tax rate on one invoice, with the issuer choosing to round up, round down, or use ordinary 4-versus-5 rounding.
Read that carefully, because it is not the rule most systems implement. It is not per line, which is what a system that rounds each row does. And it is not per document, which is what ours does. It is per rate band, and Japan runs two of them at once — 10% generally, 8% on food and some subscriptions — so an invoice carrying both is the ordinary case rather than an edge case.
| Where rounding happens | What that produces | Japan |
|---|---|---|
| Once per line | Each row is payable; the total is the sum of roundings and can drift from the tax on the total. | Not permitted under the qualified invoice system. |
| Once per document | The total is payable; no per-rate figure exists to show. | What ours does. Not the rule, and it cannot become the rule without a per-rate subtotal. |
| Once per rate, per document | Each rate band carries a payable figure and the document shows it. | The requirement. |
The invoice has a shape, and the shape needs a number we do not hold
A qualified invoice is the older classified invoice with three things added: the issuer's registration number, the applicable tax rate, and the consumption tax categorized by tax rate. Of those three, we hold the middle one and we hold it well — the rate is stored on the invoice line as a figure captured when the document is raised, so it never drifts when someone edits a reference table two years later.
The other two are absent rather than weak. There is no registration number column anywhere — not on suppliers, not on customers, not on the organization itself. And the consumption tax lives on the invoice header as a single figure, so we can tell you the rate each line carried and the total the document bears, and not the one number in between. That missing middle number is also what blocks the rounding rule, which is why the two are one piece of work rather than two.
What to do with this if you are buying something
Three tests, none of which requires a demonstration script or a salesperson, and all of which work on any system including ours.
- Raise one invoice with prices that are not multiples of ten. Three lines, standard rate. Then look at the tax figure and ask whether it is an amount of money. This is the whole test for whether currency precision is data or an assumption.
- Put two different tax rates on one document and look for the tax shown for each. If the system can only give you a total, it is not producing the breakdown the document requires, however right that total is.
- Ask where rounding happens — per line, per document, or per rate band — and then check the answer against an invoice rather than against the answer. The three produce different numbers on the same data, and only one of them is a compliance question with a right answer in your market.
We publish our own answers to all three above, which is the point of writing this rather than a general piece about rounding. The figure is ¥423.4, the fix is on our list with a price on it, and it is not conditional on anybody buying anything. If it is disqualifying for your next filing period, that is a reasonable conclusion and better reached from a blog post than from an implementation.