还在reduce求和吗?该使用Math.sumPrecise()方法啦
原文中文,约4200字,阅读约需10分钟。
📝
内容提要
文章介绍JavaScript新增的`Math.sumPrecise()`方法,用于精确数组求和,解决浮点精度和大数计算问题。该方法支持小数、大整数及特殊值(如`-0`、`Infinity`),并附有Polyfill实现及边界测试用例,兼容性良好,推荐替代`reduce()`方法。
🔎
延伸解读
为什么reduce求和会出错
JavaScript中的浮点数采用IEEE 754双精度表示,导致0.1+0.2不等于0.3。此外,当数值极大或极小时,直接相加可能丢失精度,例如[1e20, 0.1, -1e20]用reduce求和得到0而非0.1。传统解决方法如乘以倍数或使用toPrecision(),但toPrecision()对极大数无效。Math.sumPrecise()通过Neumaier补偿算法,能正确处理这些情况。
Math.sumPrecise()的边界行为
该方法对特殊值有明确处理:空数组返回0,[-0]返回-0,[-0,0]返回0(正零优先),[Infinity,-Infinity]返回NaN,含NaN则返回NaN。此外,它接受任意可迭代对象,如Set和生成器,不仅限于数组。这些行为与reduce的简单相加不同,使用时需注意预期结果。
兼容性与Polyfill注意事项
Math.sumPrecise()是较新的API,虽然主流浏览器已支持,但旧环境可能缺失。文章提供了Polyfill实现,基于Neumaier补偿算法,并包含参数校验和边界处理。引入Polyfill时需注意其依赖Symbol.iterator和Number.isNaN等ES6特性,确保运行环境支持。
🏷️