首页/数据/SQL 速查/ROUND 四舍五入与精度陷阱
函数速查60 条

ROUND 四舍五入与精度陷阱

按小数位舍入:整数位也可通过负的位数处理;浮点参数的舍入行为与十进制精度有关,金额场景应使用 DECIMAL。

SQL 速查数据更新于 2026-10-13

ROUND 是什么

按指定小数位做舍入,位数可以为负,表示对整数位处理。坑点在浮点:FLOAT 与 DOUBLE 无法精确表示十进制小数,ROUND 的结果可能出人意料。金额类计算一律使用 DECIMAL 或 numeric。

基本信息

语法ROUND(x[, 小数位数]),MySQL 支持负的位数
精确类型MySQL 的 DECIMAL 与 PG 的 numeric 按“远离零”舍入
浮点类型FLOAT、DOUBLE 受二进制表示影响,结果可能不符合直觉
PG 的 double按就近偶数舍入(银行家舍入),与 numeric 行为不同
典型坑ROUND(2.675, 2) 在浮点参数下可能得到 2.67
口径差异先 SUM 再 ROUND 与逐行 ROUND 再 SUM 结果不同

行为演示

行为演示
SELECT ROUND(2.345, 2);       -- 2.35:精确类型按远离零舍入
SELECT ROUND(2.675, 2);       -- 浮点参数下可能得 2.67
SELECT ROUND(1234.5678, -2);  -- 1200:MySQL 支持负位数

-- 金额场景:列定义为 DECIMAL,舍入结果才可预期
SELECT ROUND(SUM(amount), 2) AS total,         -- 先汇总再舍入
       SUM(ROUND(amount, 2)) AS row_wise_total  -- 逐行舍入再汇总,口径不同
FROM orders;

舍入行为对照

场景MySQL 8PostgreSQL
DECIMAL / numeric远离零舍入远离零舍入
FLOAT / DOUBLE受二进制表示影响double precision 就近偶数
负的位数支持 ROUND(x, -2)同样支持 round(x, -2)
取整函数CEIL、FLOOR、TRUNCATEceil、floor、trunc
金额字段建议DECIMAL(14,2)numeric(14,2)

典型使用场景

  • 金额、税率、折扣的舍入与展示
  • 指标看板统一小数位,避免同页面精度不一致
  • 百分比与分位数展示时控制精度
  • 把大数值近似到百位、千位,用于粗略展示
  • 报表核对:统一“在哪一层舍入”的口径
  • 对账差异排查:先排查是否舍入层级不同造成
  • 分账与结算:把总额按比例拆成多份,最后一份用差额补齐
  • 数据修复:把历史脏小数统一舍入到规范的两位小数
舍入层级会改变结果:先汇总再舍入与逐行舍入再汇总,在大量小数运算下能差出可观金额。财务类报表必须在口径文档里写明在哪一层舍入。
分摊场景的尾差要单独处理:把 100 元按 3 份分摊,逐份 ROUND 会得到 33.33 乘 3 等于 99.99,最后一份应该用总额减去前两份之和补齐,而不是再舍入一次。
在浮点列上做金额计算是隐患:二进制无法精确表示 0.1 这类十进制小数,反复累加会积累误差。金额字段请使用 DECIMAL 或 numeric 类型。

易错点

  • 在浮点列上做金额运算:累积误差会导致对账不平,应改用 DECIMAL 或 numeric
  • 用 ROUND 当截断用:它是舍入不是截断,需要截断时用 TRUNCATE 或 trunc
  • 同一报表混用不同舍入层级:总数与明细相加对不上,先固定口径
  • 以为整数位不能舍入:传入负的位数即可,例如 ROUND(x, -2) 舍入到百位

数据来源与参考

  • MySQL 8.0 Reference Manual · ROUND
  • PostgreSQL Documentation · Mathematical Functions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌