round() 实现的是 ROUND_HALF_EVEN(银行家舍入),非“逢五进一”;如 round(2.5)→2、round(3.5)→4;浮点精度误差导致输入值失真(如1.255实际存为1.254999...),加剧结果偏差;需用 Decimal 配合 quantize() 和 ROUND_HALF_UP 实现严格五入。

Python 的 round() 从不执行“逢五进一”——它根本不是按这个规则设计的。你看到的“偶数舍入”,就是它的正常行为,不是 bug,也不是精度问题导致的意外。
为什么 round(2.5) 返回 2 而不是 3
因为 round() 实现的是 ROUND_HALF_EVEN(也叫银行家舍入),不是 ROUND_HALF_UP。当待舍入部分恰好是 0.5(或对应小数位的 5)且后面无非零数字时,它会检查保留位末位:是奇数则进,是偶数则舍,目标是让结果朝偶数靠拢。
-
round(2.5)→ 2(2 是偶数,舍) -
round(3.5)→ 4(3 是奇数,进) -
round(4.5)→ 4(4 是偶数,舍) -
round(-1.5)→ -2(-2 是偶数,比 -1 更靠近 0?不,是更靠近偶数:-2 和 0 都是偶数,但 -2 是离 -1.5 更近的偶数)
浮点表示误差会让“五”根本不存在
你以为你在对 1.255 做“五入”,但 1.255 在内存里大概率是 1.2549999999999999(用 repr(1.255) 就能验证)。这时 round(1.255, 2) 实际是在对一个略小于 1.255 的数舍入,自然得 1.25,而非 1.26。
创建 Flask + Vue.js 全栈项目,采用单端口架构、uv 依赖管理、结构化日志和生产级前端设计。当用户要求以下操作时触发:创建新的 Flask+Vue 项目、搭建 Web 应用、构建全栈 Python+Vue 应用、初始化 Flask Web 项目、设置单端口 Flask 前后端项目。触发词:新建项目、创建项目、搭建项目、Flask项目、Vue项目。
- 所有无法用二进制有限位精确表示的十进制小数(如
0.1、0.25、2.675)都存在这种隐式偏差 - 这种偏差和
ROUND_HALF_EVEN规则叠加,会让结果更难预测 -
round(2.675, 2)返回2.67,不是规则错了,是输入值本身已失真
想严格“逢五进一”,别碰 round(),用 decimal
硬改 round() 行为不可靠(比如加 0.5 再 int() 会崩坏负数、大数、浮点误差)。唯一可控路径是绕过 float,用十进制算术:
立即学习“Python免费学习笔记(深入)”;
- 必须用字符串初始化:
Decimal('1.255'),不能写Decimal(1.255) - 调用
quantize()并显式指定rounding=ROUND_HALF_UP - 示例:
Decimal('1.255').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)→Decimal('1.26') - 注意:性能下降明显,每秒万级以下数值处理才适合用
真正容易被忽略的点是:你可能以为只要避开 .5 就安全了,但浮点存储本身就在悄悄改写你的输入——哪怕你没写 .5,只要原始字面量在二进制中不精确,round() 就是在对一个“假数”做银行家舍入。

















