-
Notifications
You must be signed in to change notification settings - Fork 2
/
spec.html
63 lines (60 loc) · 3.31 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<meta charset="utf-8">
<pre class="metadata">
title: Math.sumPrecise
status: proposal
stage: 2.7
copyright: false
contributors: Kevin Gibbons
</pre>
<div id="metadata-block">
<h1>Contributing to this Proposal</h1>
<p>You can discuss this proposal <a href="https://github.com/tc39/proposal-math-sum">on GitHub</a>.</p>
</div>
<emu-clause id="sec-proposal-intro">
<h1>Introduction</h1>
<p>This proposal adds a method for summing multiple numbers.</p>
</emu-clause>
<emu-clause id="sec-math.sumprecise">
<h1>Math.sumPrecise ( _items_ )</h1>
<p>Given an iterable of Numbers, this function sums each value in the iterable and returns their sum. If any value is not a Number it throws a *TypeError* exception.</p>
<p>It performs the following steps when called:</p>
<emu-alg>
1. Perform ? RequireObjectCoercible(_items_).
1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~).
1. Let _state_ be ~minus-zero~.
1. Let _sum_ be 0.
1. Let _count_ be 0.
1. Let _next_ be ~not-started~.
1. Repeat, while _next_ is not ~done~,
1. Set _next_ to ? IteratorStepValue(_iteratorRecord_).
1. If _next_ is not ~done~, then
1. Set _count_ to _count_ + 1.
1. If _count_ ≥ 2<sup>53</sup>, then
1. Let _error_ be ThrowCompletion(a newly created *RangeError* object).
1. Return ? IteratorClose(_iteratorRecord_, _error_).
1. NOTE: The above case is not expected to be reached in practice and is included only so that implementations may rely on inputs being "reasonably sized" without violating this specification.
1. If _next_ is not a Number, then
1. Let _error_ be ThrowCompletion(a newly created *TypeError* object).
1. Return ? IteratorClose(_iteratorRecord_, _error_).
1. Let _n_ be _next_.
1. If _state_ is not ~not-a-number~, then
1. If _n_ is *NaN*, then
1. Set _state_ to ~not-a-number~.
1. Else if _n_ is *+∞*<sub>𝔽</sub>, then
1. If _state_ is ~minus-infinity~, set _state_ to ~not-a-number~.
1. Else, set _state_ to ~plus-infinity~.
1. Else if _n_ is *-∞*<sub>𝔽</sub>, then
1. If _state_ is ~plus-infinity~, set _state_ to ~not-a-number~.
1. Else, set _state_ to ~minus-infinity~.
1. Else if _n_ is not *-0*<sub>𝔽</sub> and _state_ is either ~minus-zero~ or ~finite~, then
1. Set _state_ to ~finite~.
1. Set _sum_ to _sum_ + ℝ(_n_).
1. If _state_ is ~not-a-number~, return *NaN*.
1. If _state_ is ~plus-infinity~, return *+∞*<sub>𝔽</sub>.
1. If _state_ is ~minus-infinity~, return *-∞*<sub>𝔽</sub>.
1. If _state_ is ~minus-zero~, return *-0*<sub>𝔽</sub>.
1. Return 𝔽(_sum_).
1. NOTE: The value of _sum_ can be computed without arbitrary-precision arithmetic by a variety of algorithms. One such is the "Grow-Expansion" algorithm given in <i>Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates</i> by Jonathan Richard Shewchuk. A more recent algorithm is given in "<a href="https://arxiv.org/abs/1505.05571">Fast exact summation using small and large superaccumulators</a>", code for which is available at <a href="https://gitlab.com/radfordneal/xsum">https://gitlab.com/radfordneal/xsum</a>.
</emu-alg>
</emu-clause>