Skip to content

Commit a453c2e

Browse files
Reference for stage 3 math-sum (mdn#38387)
* Reference for stage 3 math-sum * Remove performance claim * Update files/en-us/web/javascript/reference/global_objects/math/index.md Co-authored-by: Hamish Willee <hamishwillee@gmail.com> --------- Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
1 parent c1f184a commit a453c2e

File tree

2 files changed

+89
-0
lines changed
  • files/en-us/web/javascript/reference/global_objects/math

2 files changed

+89
-0
lines changed

files/en-us/web/javascript/reference/global_objects/math/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ Unlike most global objects, `Math` is not a constructor. You cannot use it with
109109
- : Returns the hyperbolic sine of the input.
110110
- {{jsxref("Math.sqrt()")}}
111111
- : Returns the positive square root of the input.
112+
- {{jsxref("Math.sumPrecise()")}}
113+
- : Returns the sum of a passed iterable of numbers, avoiding floating point precision loss in intermediate results.
112114
- {{jsxref("Math.tan()")}}
113115
- : Returns the tangent of the input.
114116
- {{jsxref("Math.tanh()")}}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
title: Math.sumPrecise()
3+
slug: Web/JavaScript/Reference/Global_Objects/Math/sumPrecise
4+
page-type: javascript-static-method
5+
browser-compat: javascript.builtins.Math.sumPrecise
6+
---
7+
8+
{{JSRef}}
9+
10+
The **`Math.sumPrecise()`** static method takes an iterable of numbers and returns the sum of them. It is more precise than summing them up in a loop, because it avoids floating point precision loss in intermediate results.
11+
12+
{{InteractiveExample("JavaScript Demo: Math.sumPrecise()")}}
13+
14+
```js interactive-example
15+
console.log(Math.sumPrecise([1, 2]));
16+
// Expected output: 3
17+
18+
console.log(Math.sumPrecise([1e20, 0.1, -1e20]));
19+
// Expected output: 0.1
20+
```
21+
22+
## Syntax
23+
24+
```js-nolint
25+
Math.sumPrecise(numbers)
26+
```
27+
28+
### Parameters
29+
30+
- `numbers`
31+
- : An [iterable](/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol) (such as an {{jsxref("Array")}}) of numbers.
32+
33+
### Return value
34+
35+
A number that is the sum of the numbers in the `numbers` iterable. If the iterable is empty, the return value is `-0` (_not_ `0`).
36+
37+
### Exceptions
38+
39+
- {{jsxref("TypeError")}}
40+
- : If `numbers` is not an iterable, or if any of the numbers in the iterable is not of the number type.
41+
42+
## Description
43+
44+
Because `sumPrecise()` is a static method of `Math`, you always use it as `Math.sumPrecise()`, rather than as a method of a `Math` object you created (`Math` is not a constructor).
45+
46+
The method is called `Math.sumPrecise()` because it is more precise than naïvely summing up numbers in a loop. Consider the following example:
47+
48+
```js
49+
let sum = 0;
50+
const numbers = [1e20, 0.1, -1e20];
51+
for (const number of numbers) {
52+
sum += number;
53+
}
54+
console.log(sum); // 0
55+
```
56+
57+
The output is 0. This is because `1e20 + 0.1` cannot be represented precisely in 64-bit floats, so the intermediate result is rounded to `1e20`. Then, the sum of `1e20` and `-1e20` is `0`, so the final result is `0`.
58+
59+
`Math.sumPrecise()` avoids this issue by using some specialized summing algorithm. It works as if the floating point numbers are summed up using their precise mathematical values, and the final result is then converted to the nearest representable 64-bit float. This still cannot avoid the `0.1 + 0.2` precision problem:
60+
61+
```js
62+
console.log(Math.sumPrecise([0.1, 0.2])); // 0.30000000000000004
63+
```
64+
65+
Because the floating point literals `0.1` and `0.2` already represent mathematical values greater than `0.1` and `0.2`, and their sum's closest 64-bit float representation is actually `0.30000000000000004`.
66+
67+
## Examples
68+
69+
### Using Math.sumPrecise()
70+
71+
```js
72+
console.log(Math.sumPrecise([1, 2, 3])); // 6
73+
console.log(Math.sumPrecise([1e20, 0.1, -1e20])); // 0.1
74+
```
75+
76+
## Specifications
77+
78+
{{Specifications}}
79+
80+
## Browser compatibility
81+
82+
{{Compat}}
83+
84+
## See also
85+
86+
- [Polyfill of `Math.sumPrecise` in `core-js`](https://github.com/zloirock/core-js#mathsumprecise)
87+
- {{jsxref("Array.prototype.reduce()")}}

0 commit comments

Comments
 (0)