消費税の税込→税抜で1円ずれる理由 — 10%なら11円に1つ届かない
税抜価格から税込価格を出し、別の画面では税込から税抜に戻す。どちらも「税率を掛ける」「1.1で割る」だけに見えるが、消費税額の1円未満をどう丸めるかを両方向でそろえないと、戻した税抜をもう一度税込にしたとき元の額にならない。
この記事では ハシトシステムの消費税計算ツール のコードを読み、税抜→税込と税込→税抜の往復がどれだけ崩れるか、そもそも作れない税込額がどれだけあるかを、1円〜10万円の全数で数える。最後に、インボイス(適格請求書)での端数処理の単位も国税庁の Q&A で確認する。
ツールは2つの向きで丸め方が違う
ツールの計算部分は次の2行である(index.html の calc() から)。
1 | |
- 税抜→税込: 消費税額
税抜 × 税率の1円未満を切り捨てる。 - 税込→税抜:
税込 ÷ (1 + 税率)を四捨五入して税抜にし、税込との差を消費税額にする。
ページの解説にもこの2つの丸め方がそのまま書かれている。税込は整数なので、税抜を四捨五入することは、消費税額を(ほぼ)四捨五入することと同じになる。つまり片方は切り捨て、もう片方は四捨五入で、向きによって消費税額の丸め方が違う。
たとえば税込60,000円(10%)では、60000 × 10 / 110 = 5454.54… なので、切り捨てなら消費税は5,454円、ツールの税込→税抜では税抜54,545円・消費税5,455円になる。どちらが正しいというものではなく、後で見るとおり端数処理の方法は事業者が選べる。ただ、同じシステムの中で2つの向きを混ぜると、往復で1円ずれる。
切り捨てでは「作れない税込額」がある
消費税を切り捨てる場合、税込は 税抜 + floor(税抜 × 0.1) = floor(税抜 × 1.1) になる。税抜を1円ずつ増やすと、税込はたいてい1円ずつ増えるが、税抜が10円増えるたびに消費税も1円増えるので、そこで税込は2円跳ぶ。
| 税抜 | 消費税(切り捨て) | 税込 |
|---|---|---|
| 8 | 0 | 8 |
| 9 | 0 | 9 |
| 10 | 1 | 11 |
| 11 | 1 | 12 |
税込10円になる税抜は存在しない。同じ理由で21円、32円、43円……と、10%では11円に1つ、税込に現れない額がある。8%なら税抜12.5円ごとに消費税が1円増えるので、27円に2つ(13円、26円、40円、53円……)が抜ける。
税込→税抜の画面にこうした額が入力されると、どんな税抜を返しても税抜→税込では元に戻らない。ツールの税込→税抜に10円を入れると税抜9円・消費税1円を返すが、税抜9円を税抜→税込にかけると消費税0円・税込9円になる。
切り捨てと対になる逆算は切り上げ
floor(税抜 × 1.1) = 税込 を満たす税抜は、税込 ≤ 税抜 × 1.1 < 税込 + 1 の範囲にある整数である。範囲の幅は 1 ÷ 1.1 で1より小さいので、整数は多くても1つしかなく、あるならそれは ceil(税込 ÷ 1.1) になる。
浮動小数の 1.1 での割り算を避けるなら、整数だけで次のように書ける。
1 | |
戻した税抜をもう一度 税抜 + floor(税抜 × 税率 / 100) にかけ、元の税込に一致しなければ、その税込は切り捨てでは作れない額である。画面で「この税込額になる税抜はありません」と出すか、近い額を案内するかは仕様で決める。
実際に試す
Node.js 24.11.1(Windows 11)で実行した。依存パッケージは要らない。次の内容を tax-roundtrip.mjs として保存する。
1 | |
1 | |
出力:
1 | |
税込を四捨五入で税抜に戻すと、10%では1円〜10万円の45,455件(約45%)で、税抜→税込にかけ直したとき元の税込に戻らない。この数には、そもそも作れない税込額も含まれる。切り上げで戻すと、10%では90,909件で往復が成り立ち、成り立たない9,091件はすべて切り捨てでは作れない税込額である。8%でも同じで、92,593件が成り立ち、7,407件が届かない額だった。
6->5->5 は、税込6円を四捨五入で戻すと税抜5円(6 ÷ 1.1 = 5.45…)になり、税抜5円の消費税は切り捨てで0円なので税込5円に戻る、という意味である。切り上げなら税抜6円になり、消費税0円で税込6円に戻る。
インボイスでは「1枚につき税率ごとに1回」
国税庁の「適格請求書等保存方式に関するQ&A」の問57は、適格請求書に書く消費税額等に1円未満の端数が出る場合、一の適格請求書につき税率ごとに1回の端数処理を行う必要がある、と答えている(根拠として消費税法施行令70条の10と消費税法基本通達1-8-15を挙げている)。同じ回答で、次の2点も書かれている。
- 切上げ、切捨て、四捨五入などの端数処理の方法は任意に選べる。
- 個々の商品ごとに消費税額等を計算して1円未満を処理し、その合計を消費税額等として記載することは認められない。
問57の記載例では、税込60,000円(10%対象)を 60,000円 × 10/110 ≒ 5,454円、税込40,000円(8%対象)を 40,000円 × 8/108 ≒ 2,962円 としている。これは切り捨てた値と一致する。
上の出力の最後の行は、この違いを小さな例で見たものである。税抜98円の明細が3行ある請求書で、明細ごとに消費税を切り捨てると9円×3 = 27円、税率ごとに合計294円から1回で出すと29円になる。明細ごとに丸めると、行数が増えるほど合計の消費税額が小さく出やすい。
実装するときの注意
- 丸め方は両方向で対にする。税抜→税込で消費税を切り捨てるなら、税込→税抜は
ceil(税込 × 100 / (100 + 税率))で戻し、もう一度税込にかけて一致を確かめる。四捨五入で戻すと半数近くで1円ずれる。 - 作れない税込額を想定する。消費税を切り捨てる場合、10%では11円に1つ、8%では27円に2つの税込額は、どの税抜からも出てこない。入力をそのまま受け付けるなら、その旨を示す。
- 請求書の消費税は税率ごとの合計から1回で出す。明細ごとの消費税を足した額は、インボイスの消費税額等としては認められない(国税庁 Q&A 問57)。明細ごとの税額を画面に出すのは構わないが、合計欄とは別物として扱う。
- 整数で計算する。
inc / 1.1のような浮動小数の割り算は、今回の範囲(1円〜100万円、10%と8%)では整数版と結果が一致したが、税率を任意にすると保証できない。円は整数、税率は百分率の整数で持ち、割り算は最後に1回だけにする。
まとめ
- ハシトシステムの消費税計算ツールは、税抜→税込で消費税を切り捨て、税込→税抜で税抜を四捨五入する。向きによって消費税額の丸め方が違うので、往復すると10%では1円〜10万円の約45%で1円ずれる。
- 消費税を切り捨てる場合、10%では税込10円・21円・32円のように11円に1つ、作れない税込額がある。切り捨てと対になる逆算は
ceil(税込 × 100 / (100 + 税率))で、それ以外の額では往復が成り立つ。 - インボイスでは、消費税額等の端数処理は1枚の適格請求書につき税率ごとに1回で、方法(切上げ・切捨て・四捨五入)は任意、商品ごとに丸めて合計するのは不可(国税庁 Q&A 問57)。
法人番号を持つ事業者のインボイス登録番号は「T + 法人番号13桁」になる。法人番号の検査用数字は「法人番号の検査用数字をJSで計算する」で扱った。
ツール: 消費税計算(ハシトシステム)。税抜→税込と税込→税抜を切り替えて、10%・8%・任意の税率で税抜・消費税額・税込を出す。計算はブラウザ内で完結する。