配了多年精度计算,今天才知道浮点把结果偷偷吃掉了——Math.sumPrecise() 把这件事从根上原生化了

做过财务结算、统计数据,甚至只是给图表算个累计值的工程师,大概都见过这个经典场面:0.1 + 0.2 的结果不是 0.3,而是 0.30000000000000004——这个笑话说了好多年,2026 年 JavaScript 终于给出了一个官方的解法。

它不是修 0.1 + 0.2 的问题

先别急着高兴。Math.sumPrecise() 不能让 0.1 + 0.2 变成精确的 0.3,这件事 IEEE 754 浮点数的底层限制改不了。这个 API 解决的是另一个更隐蔽、但在实际业务里更致命的问题:累积误差。

看这个例子:

// 经典 reduce 求和
const values = [1e20, 0.1, -1e20];
const total = values.reduce((a, b) => a + b, 0);
console.log(total); // 0

// Math.sumPrecise 求和
console.log(Math.sumPrecise(values)); // 0.1

1e20 + 0.1 这一步,在 IEEE 754 双精度浮点数里,0.1 相对于 1e20 太小了,直接被四舍五入成了 0。然后 1e20 + (-1e20) = 0,最终结果 0。数学上等于 0.1,但 reduce 算出来是 0。

这种事在真实场景里比想象中常见:报表合计差个几分钱、日志聚合数字对不上、传感器数据积分越算越偏——往往不是算法错了,是浮点精度在中间步骤悄悄吃了你的数据。

API 怎么用

// 接收任意可迭代对象
const total = Math.sumPrecise([10, 20, 30]); // 60

// 财务场景
const orders = [899.99, 1299.00, 59.99, 199.00];
console.log(Math.sumPrecise(orders)); // 2457.98

// 科学计算
const measurements = [1e10, 0.0001, -1e10];
console.log(Math.sumPrecise(measurements)); // 0.0001

// 降级兼容
const sum = Math.sumPrecise
  ? Math.sumPrecise(values)
  : values.reduce((a, b) => a + b, 0);

底层原理是”高精度求和算法”:不是一次次做 sum + nextNumber 再四舍五入,而是先把所有数字以高精度累加,最后再转换成最接近的可表示 64 位浮点数。MDN 的描述是”仿佛先用精确数学值求和,再取最近的可表示浮点结果”。

浏览器支持

浏览器 版本
Chrome 147+
Firefox 137+
Safari 26.2+
Edge 147+

它是 ES2026 的一部分,2026 年 4 月进入 Baseline “Newly Available”。目前全球覆盖率约 79%(caniuse 数据),不支持的浏览器可以自己写降级函数,等覆盖率再涨一到两年就稳了。

什么时候用它

应该用: 财务金额累加、统计数据合计、传感器读数积分、任何”差个零点零几会出大事”的场景。

不需要用: UI 动画参数、简单的 UI 数字展示、用户可见度不高的装饰性计数。

说白了,这是一个”有体感才值得用”的 API——如果你的用户会因为合计差了几分钱来投诉,这个 API 就是为你准备的;如果只是给 div 里的数字做一下加法,原来的 reduce 完全够用。

下一个要写累加逻辑之前,先看一眼 Math.sumPrecise() 有没有:如果有,三行代码换掉 reduce;如果没有,想想这个场景值不值得加一个降级兼容。这个 API 不会解决 0.1 + 0.2 的问题,但它解决的是更隐蔽、更影响业务的精度丢失。2026 年了,财务计算该用更精确的方式了。

评论区

0 条评论

登录后可评论。