[点晴永久免费OA]Math.sumPrecise:0.1 + 0.2 等于 0.3 了:JavaScript 的浮点精度问题,有救了
当前位置:点晴教程→点晴OA办公管理信息系统
→『 经验分享&问题答疑 』
你一定记得JS里的这个问题,或许以前面试的时候经常被问到过 这不是 bug,是 IEEE 754 浮点数标准的"特性"。JavaScript 用 64 位浮点数表示所有数字,而 0.1 和 0.2 在二进制里都是无限循环小数,存进去的时候就已经丢了精度。两个"不精确"的数加在一起,误差就暴露了。 这个问题存在了 25 年。每个 JavaScript 开发者都踩过,每个新手教程都会提一嘴,然后告诉你"用 toFixed 修一下"或者"乘以 100 转成整数再算"。 现在,ECMAScript 2026 终于给了一个正经的解决方案: 不只是 0.1 + 0.2 的问题你可能觉得 0.1 + 0.2 的问题不痛不痒,但如果场景变复杂了呢。
想象一个场景:你在做一个财务报表,需要把 1000 笔交易金额加起来。每笔金额都是小数,比如 12.50、3.75、89.99 这种。 你大概率会这么写: 看起来没问题对吧?但这段代码的误差会随着交易数量累积。每做一次加法,中间结果就可能丢一点点精度。1000 笔下来,最终结果可能差了 0.01 甚至更多。 在财务场景里,一分钱的误差就够让你半夜被叫起来排查 bug 了。 更极端的例子: 1e20 + 0.1 的中间结果是 1e20,因为 0.1 在 1e20 面前实在太小了,直接被吞掉了。然后 1e20 + (-1e20) = 0。0.1 就这么凭空消失了。 这不是理论上的 corner case。在数据分析、科学计算、游戏物理引擎里,这种"大数吃小数"的问题每天都在发生。 Math.sumPrecise:用更聪明的算法算加法ES2026 的 用法很简单: 它接受一个可迭代对象(数组、Set、Generator 都行),返回精确的求和结果。 背后的算法叫 Shewchuk 算法,1996 年由 Jonathan Shewchuk 提出。核心思路是:不直接把数字加在一起,而是用一个数组记录所有的"误差项"。每次加法的时候,把真正的误差存起来,最后再把所有误差补偿回去。 打个比方:普通加法就像是你拿着一个有刻度误差的尺子量东西,量一次误差一点,量 100 次误差就大了。而 Shewchuk 算法是每次量完都记下"这次差了多少",最后把所有偏差加起来一次性修正。 所以它能做到"最大精度正确"——结果等价于你用无限精度算完再转回浮点数。
实际用法基础求和配合数组方法接受任何可迭代对象注意事项1. 只接受数字 跟 2. 空数组返回 -0 为什么是 -0 而不是 0?因为 -0 是浮点数加法的"单位元"。 这个设计细节很数学,但如果你的业务逻辑对 -0 和 0 有区分(比如 JSON 序列化),注意一下。 3. 性能 Shewchuk 算法比直接加法慢。它需要维护误差项数组,处理溢出边界情况。对于小数组(几十个元素),差距不大。对于大数组,差距会明显一些。 所以:日常小量数据用 浏览器支持ES2026 的提案在 2025 年 7 月达到 Stage 4,现在各浏览器的支持情况:
TypeScript 暂时还没有内置类型定义,需要自己加一行: 这个特性值得用吗?值得,但要看场景。 如果你的代码只是做简单的加减,用户看到的数字都是整数或者小数点后两位, 但如果你在做:
而且用法太简单了,直接把 最后JavaScript 的浮点精度问题从 1995 年就存在了。25 年来,开发者们用各种 workaround 应对:乘 100 转整数、用 toFixed、引入 decimal.js 这样的第三方库。 现在语言层面终于给了一个原生方案。不是修复浮点数本身(那会破坏整个生态),而是提供一个"精确求和"的工具。 这是一个小特性,但解决了真实存在了 25 年的痛点。 下次你要在代码里做浮点数累加的时候,试试 阅读原文:https://mp.weixin.qq.com/s/Zw3Z21FVq5iQXIJ0BdXJFA 该文章在 2026/5/11 10:04:26 编辑过 |
关键字查询
相关文章
正在查询... |