round()用于数值计算,返回数字;format()用于字符串格式化,返回带千分位的文本,误用于计算或排序将导致错误。
mysql 中 round() 和 format() 的区别与误用场景
round(value, decimals) 是四舍五入,返回数值类型;format(value, decimals) 是格式化字符串,带千分位逗号,返回 text。很多人用 format 做计算后续字段,结果报错或排序错乱——因为它是字符串。
- 需要参与后续加减乘除?必须用
ROUND(),比如ROUND(price * 1.15, 2) - 只是最终展示给报表或前端?
FORMAT()更省事,但别把它塞进 WHERE 或 ORDER BY -
FORMAT(1234.567, 2)返回"1,234.57",而ROUND(1234.567, 2)返回1234.57(纯数字) - 注意:FORMAT 受 locale 影响,中文环境可能输出顿号或不同小数点,生产环境慎用
PostgreSQL 里用 ROUND() 还是 to_char() 控制小数位
PostgreSQL 的 ROUND() 行为和 MySQL 一致,但精度处理更严格;to_char() 是格式化专用函数,类似 MySQL 的 FORMAT,但不加千分位,可控性更强。
- 做中间计算?只用
ROUND(<code>expr,n),例如ROUND((a + b) / c, 3) - 要固定宽度、补零(如 9.5 显示为
"09.500")?用to_char(<code>value, 'FM000.000') -
to_char()返回 text,不能直接参与算术;若需“先格式再计算”,说明设计有误,应拆成两步 - 性能上,
ROUND()比to_char()快一个数量级,高频聚合查询避免后者
Python pandas 计算列后保留两位小数的三种写法陷阱
pandas 里看似简单的 df['x'].round(2) 很多时候不是你想要的“显示效果”,而是真正截断/四舍五入后的数值;apply(lambda x: f'{x:.2f}') 是转字符串,后续无法 sum/max。
- 想存为数值且固定两位小数?用
df['x'] = df['x'].round(2)—— 注意这是浮点近似,不是精确十进制 - 要精确货币计算?改用
decimal类型预处理,pandas 原生不支持 Decimal 列运算,得用df['x'].apply(Decimal).apply(lambda d: d.quantize(Decimal('0.01'))) - 仅导出时格式化?在
to_csv()里加参数float_format='%.2f',比每列单独处理更安全 - 别用
pd.options.display.float_format改全局显示——它只影响 print,不改变实际值,容易误判数据质量
前端 JavaScript 处理后端传来的数字精度问题
后端传 19.995,JS 用 toFixed(2) 得到 "20.00"(正确),但传 1.005 却可能得 "1.00"——这是浮点误差导致的 toFixed 不稳定行为。
- 不要直接对原始 number 调
toFixed(),先用Math.round(num * 100) / 100强制四舍五入 - 更稳妥:用
Number(val.toFixed(3)).toFixed(2)多兜一道,缓解浮点累积误差 - 如果后端能改,建议统一传字符串或整数单位(如“分”),彻底规避 JS 浮点坑
- Intl.NumberFormat 是现代方案,但要注意 Safari 对
minimumFractionDigits的兼容性,iOS 14 以下可能忽略
最麻烦的不是不会用函数,而是没分清「计算」和「展示」两个阶段——混在一起,小数位就变成玄学。











