You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中浮点值运算出现非预期高精度结果的技术问询

理解并解决PostgreSQL浮点数求和的精度异常问题

这其实是浮点数(尤其是PostgreSQL里默认的FLOAT/FLOAT(53),也就是IEEE 754标准的双精度浮点数)的经典二进制精度限制问题,可不是PostgreSQL的bug哦!

问题根源:浮点数的二进制存储限制

咱们先搞懂为什么会出现这种“奇怪”的结果:十进制里的很多小数(比如0.05、0.64)没法用二进制浮点数精确表示,它们在存储时已经是一个近似值了。举个例子:

  • CAST(669.05 AS FLOAT)实际存储的是一个接近669.05但略有偏差的二进制近似值
  • CAST(1.64 AS FLOAT)同理,也是一个近似值

当这两个近似值相加时,误差被累积,就出现了670.6899999999999这种看起来不符合预期的结果。而你测试的1.63刚好运气好,两个近似值相加后的误差刚好被抵消到了能显示为670.68的程度,但这只是表象,底层的浮点值其实还是近似的。

另外你提到FLOAT(53)也有同样问题,这很正常——PostgreSQL里的FLOAT(53)就是双精度浮点数,和默认的FLOAT完全等价,本质都是IEEE 754标准的64位浮点数,所以精度限制是一样的。

解决方案:根据业务场景选择合适的处理方式

针对你的业务场景,有两种靠谱的处理思路:

1. 优先使用精确十进制类型(推荐精度敏感场景)

如果你的业务对精度要求很高(比如财务、金额计算),别再用FLOAT了,改用PostgreSQL的NUMERIC(或DECIMAL,两者完全等价)类型。它是基于十进制精确存储的,能完美避免这类精度问题。

比如把你的求和语句改成:

SELECT CAST(669.05 AS NUMERIC) + CAST(1.64 AS NUMERIC);

执行后就能得到精确的670.69。

对于全表运算的场景,直接把涉及计算的字段转换成NUMERIC再运算:

SELECT numeric_column_1 / CAST(numeric_column_2 AS NUMERIC) FROM input_table;

这样就能彻底解决大量精度异常的问题,不用再在应用层额外处理。

2. 用ROUND函数控制显示精度(适合性能优先场景)

如果你的业务必须用FLOAT(比如涉及大量科学计算,对性能要求更高),可以在查询结果里用ROUND函数指定精度,把近似值格式化成符合预期的小数位数:

SELECT ROUND(CAST(669.05 AS FLOAT) + CAST(1.64 AS FLOAT), 2);

这样输出结果就是670.69。不过要注意:ROUND只是改变了显示的格式,底层的浮点值还是近似的,只是输出时取了指定的精度。

总结

核心就是选对数据类型:

  • 精度优先(比如金额、财务计算):用NUMERIC
  • 性能优先且能接受近似值:用FLOAT+ROUND控制显示精度

内容的提问来源于stack exchange,提问作者Shashank V C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:12:42