Math.sumPrecise()

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

Math.sumPrecise() 静态方法接受一个可迭代对象(iterable)的数字,并返回它们的和。与在循环中求和相比,它更精确,因为它避免了中间结果中的浮点精度损失。

试一试

console.log(Math.sumPrecise([1, 2]));
// Expected output: 3

console.log(Math.sumPrecise([1e20, 0.1, -1e20]));
// Expected output: 0.1

语法

js
Math.sumPrecise(numbers)

参数

numbers

一个数字的可迭代对象(例如Array)。

返回值

一个数字,即 numbers 可迭代对象中所有数字的和。如果可迭代对象为空,则返回值为 -0不是 0)。

异常

TypeError

如果 numbers 不是一个可迭代对象,或者可迭代对象中的任何数字不是数字类型。

描述

因为 sumPrecise()Math 的静态方法,所以你总是通过 Math.sumPrecise() 来使用它,而不是作为你创建的 Math 对象的方法(Math 不是一个构造函数)。

该方法被命名为 Math.sumPrecise(),因为它比在循环中天真地求和更精确。考虑以下示例:

js
let sum = 0;
const numbers = [1e20, 0.1, -1e20];
for (const number of numbers) {
  sum += number;
}
console.log(sum); // 0

输出为 0。这是因为 1e20 + 0.1 无法用 64 位浮点数精确表示,所以中间结果被四舍五入为 1e20。然后,1e20-1e20 的和为 0,因此最终结果为 0

Math.sumPrecise() 通过使用一些特殊的求和算法来避免这个问题。它的工作方式就像浮点数是使用它们的精确数学值求和一样,然后最终结果被转换为最接近的可表示 64 位浮点数。这仍然无法避免 0.1 + 0.2 的精度问题:

js
console.log(Math.sumPrecise([0.1, 0.2])); // 0.30000000000000004

因为浮点数字面量 0.10.2 已经代表了大于 0.10.2 的数学值,而它们的和最接近的 64 位浮点表示实际上是 0.30000000000000004

示例

使用 Math.sumPrecise()

js
console.log(Math.sumPrecise([1, 2, 3])); // 6
console.log(Math.sumPrecise([1e20, 0.1, -1e20])); // 0.1

规范

规范
Math.sumPrecise
# sec-math.sumprecise

浏览器兼容性

另见