年终奖 36001 比 36000 多缴 2310 元,Excel 直接乘税率算错了

5 阅读8分钟

我把年终奖填成 36000 元,页面算出应缴 1080 元。改成 36001 元,应缴变成 3390.10 元。

多发 1 元,多缴 2310.10 元,到手反而少 2309.10 元。

用 Excel 直接乘税率的写法会算出 1080.03 元,看着只比 36000 元那档多 3 分钱,其实漏了速算扣除数。

图 1:默认输入(月薪 20000、五险一金 3200、专项附加扣除 2000、年终奖 60000)下两套算法的结果与结论

在线案例与源码:atomgit.com/deli007/dem… 成品只有一个 index.html,双击就能打开,不联网也能算。

一、为什么值得看:多 1 元,税差可能上千元

年终奖的税率不是拿奖金总额直接乘出来的。

先拿奖金除以 12,用商去查「按月换算后的综合所得税率表」,再用奖金乘对应税率,减去速算扣除数。

36000 除以 12 正好是 3000,落在 3% 那一档,速算扣除数是 0,税额 1080 元。

36001 除以 12 是 3000.08,越过 3000 这条线,掉进 10% 那一档,速算扣除数是 210,税额 3390.10 元。

同一套规则,一个月少 1 元,一个月少 2000 多元。这就是临界点的由来。

图 2:两张阶梯税率条形图,高亮当前所处档位

二、准备环境:进入码道 Web,把税率表和自检写进需求

浏览器打开码道 Web 版:devcloud.cn-north-4.huaweicloud.com/chat?source… ,登录后就能在对话框里写需求,不需要装软件。

码道有三种使用方式:WebUI(浏览器对话)、TUI(终端命令行)和桌面 IDE(IDE 插件)。本文用 WebUI 版演示。

这轮需求里最值钱的是三句话。

第一句:两张税率表的数字直接写死在需求里,别让它自己回忆。税收数字记错一位,整页结论都是错的。

第二句:要两种口径同屏对照,年终奖单独计税和并入综合所得各算一遍,最后给一句「哪种更省」。

第三句:页面自己带断言。我列了 9 条标准答案,比如 36000 元对应 1080 元、36001 元对应 3390.10 元、逐月预扣合计要等于年度口径应缴税额。

生成过程中模型有一次思考过长、回复被截断。我发了一句「继续」,它接着把文件写完,页面才跑起来。

三、一屏看清:页面上的六块内容

最上面是输入区:月薪、每月五险一金、每月专项附加扣除、年终奖金额、计发月数,最后跟着一句口径说明。

往下是两张结果卡,左边是年终奖单独计税,右边是并入综合所得,各自给出全年应缴税额和全年到手合计。

再往下是两张阶梯税率条形图,当前所处档位会高亮。

然后是工资逐月预扣表、年终奖 6 个临界点表。

最下面是错误算法对照,把「直接乘税率」和正确公式并排放。

右上角是 9 条自检徽章,全过就是 9 / 9。

四、实测:默认输入下两套算法差 3570 元

默认填的是月薪 20000 元、五险一金 3200 元、专项附加扣除 2000 元、年终奖 60000 元。

项目方案一:年终奖单独计税方案二:并入综合所得
全年应缴个税合计15,030.0018,600.00
全年到手合计246,570.00243,000.00
其中工资部分9,240.009,240.00
其中年终奖部分5,790.009,360.00 补缴
两者差额少缴 3,570.00多缴 3,570.00

工资部分的账是这样:每月 20000 元减去 5000 元减除费用、3200 元五险一金、2000 元专项附加扣除,每月计税基数是 9800 元。

12 个月累计 117,600 元,落在 10% 那一档,速算扣除数 2520,全年预扣 9240 元。

年终奖 60000 元除以 12 是 5000 元,落进 10% 档,税额 6000 减 210,等于 5790 元。

方案二把年终奖并进综合所得,计税基数变成 177,600 元,跳到 20% 档,全年 18,600 元。

结论那一行是页面自己打的:年终奖单独计税更省,全年少缴 3570 元。

图 3:逐月预扣表与 6 个临界点表并排

五、逐月预扣表:第 4 月才跳档

工资部分的税不是每月平均扣的,是按累计额算、再减去前面已扣的部分。

默认输入下,前 3 个月的累计计税基数还没过 36000 元,每月只扣 294 元。

第 4 个月累计到 39200 元,进了 10% 档,累计应纳税额变 1400 元,当月就要补 518 元。

从第 5 个月开始每月稳定扣 980 元,最后一个月累计 117,600 元,累计税额 9240 元。

月份累计应纳税所得额累计应缴税额本月预扣税额
第 1 月9,800.00294.00294.00
第 3 月29,400.00882.00294.00
第 4 月39,200.001,400.00518.00
第 12 月117,600.009,240.00980.00

表格下面还有一行提示:全年工资部分合计预扣 9240 元,等于年度口径应缴税额,工资部分汇算不用补退。

六、6 个临界点与跳升区间

临界点不止 36000 元这一个,一共 6 个。

临界点(元)该点应缴税多发 1 元应缴税多 1 元多缴跳升区间
36,000.001,080.003,390.102,310.1036,000.00 ~ 38,566.67
144,000.0014,190.0027,390.2013,200.20144,000.00 ~ 160,500.00
300,000.0058,590.0072,340.2513,750.25300,000.00 ~ 318,333.33
420,000.00102,340.00121,590.3019,250.30420,000.00 ~ 447,500.00
660,000.00193,590.00223,840.3530,250.35660,000.00 ~ 706,538.46
960,000.00328,840.00416,840.4588,000.45960,000.00 ~ 1,120,000.00

区间右端点是「追平点」:奖金涨到这个数,到手才刚好回到临界点的水平。

36000 元的追平点是 38,566.67 元。中间这段多发 1 元,到手就少 1 元以上。

七、验证与踩坑:33 项独立复算,抓到一处 1 元的注释错

我不信页面自己报的 9 / 9,所以另写了一份 Python 脚本,用 Decimal 重算了税率表、六档跳升额、六个追平点、逐月预扣和两套方案的差额。

脚本跑出来 33 / 33 项一致。

复现命令就两行,脚本在案例目录里。

cd codearts-bonus-tax-calculator
python verify_bonus_tax.py

本地预览用这条命令,然后开浏览器看。

python -m http.server 8000

追平点是用二分法逼近出来的,精度到 0.01 元,六个点分别是 38,566.67、160,500.00、318,333.33、447,500.00、706,538.46、1,120,000.00。

复算过程中抓到一处真错:页面注释原本写「36,001 元比 36,000 元多发 1 元,到手反而少 2,310.10 元」。

这个数把多缴的税额当成到手差额了。多发的 1 元本身也算收入,到手只少 2,309.10 元,多缴的税才是 2,310.10 元。

我把注释改成 2,309.10 元,并把两个数字都写在括号里。页面上的结果卡本来就算对了,错的是那一句话。

失败路径我试了四组输入。

输入页面反馈
年终奖 -100年终奖金额不能为负数
年终奖留空请输入年终奖金额
输入非数字请输入有效数字
年终奖 200000000年终奖不能超过 1 亿元

年终奖填 -100 元时,输入框变红,结果卡的数字全部换成「—」,逐月表显示「输入有误,未输出结果」,上方还有一条红色横条提示先修正红色输入项。

页面没有白屏,图表也还在,只是暂停输出结果。

图 4:年终奖改成 36001 元后的对比结果

图 5:失败路径,年终奖输入 -100 元时的红色提示与暂停输出

八、边界与不足

页面按公开的综合所得税率表估算,税率表和速算扣除数写死在代码里。

五险一金和专项附加扣除都由你手填每月固定值,页面不做缴费基数上下限、不做年中变更、不做补扣补缴。

年终奖单独计税这个口径本身有政策有效期,到期后算法可能要调,页面不会自己跟着变。

这里算的是税额,不是税务建议,具体申报以扣缴单位和税务机关为准。

九、使用码道体会

这轮最大的体会是:涉及数字的应用,必须把标准答案和断言一起写进需求。

税率表让模型自己回忆,它大概率会把速算扣除数记串一档;写死在需求里,它只用管算法和界面。

9 条自检加上我自己 33 项复算,正好互补:页面自检证明代码按我给的规则跑,独立复算证明我给的规则本身没写错。