| |
| export class Adder { |
| constructor() { |
| this._partials = new Float64Array(32); |
| this._n = 0; |
| } |
| add(x) { |
| const p = this._partials; |
| let i = 0; |
| for (let j = 0; j < this._n && j < 32; j++) { |
| const y = p[j], |
| hi = x + y, |
| lo = Math.abs(x) < Math.abs(y) ? x - (hi - y) : y - (hi - x); |
| if (lo) p[i++] = lo; |
| x = hi; |
| } |
| p[i] = x; |
| this._n = i + 1; |
| return this; |
| } |
| valueOf() { |
| const p = this._partials; |
| let n = this._n, x, y, lo, hi = 0; |
| if (n > 0) { |
| hi = p[--n]; |
| while (n > 0) { |
| x = hi; |
| y = p[--n]; |
| hi = x + y; |
| lo = y - (hi - x); |
| if (lo) break; |
| } |
| if (n > 0 && ((lo < 0 && p[n - 1] < 0) || (lo > 0 && p[n - 1] > 0))) { |
| y = lo * 2; |
| x = hi + y; |
| if (y == x - hi) hi = x; |
| } |
| } |
| return hi; |
| } |
| } |
|
|
| export function fsum(values, valueof) { |
| const adder = new Adder(); |
| if (valueof === undefined) { |
| for (let value of values) { |
| if (value = +value) { |
| adder.add(value); |
| } |
| } |
| } else { |
| let index = -1; |
| for (let value of values) { |
| if (value = +valueof(value, ++index, values)) { |
| adder.add(value); |
| } |
| } |
| } |
| return +adder; |
| } |
|
|
| export function fcumsum(values, valueof) { |
| const adder = new Adder(); |
| let index = -1; |
| return Float64Array.from(values, valueof === undefined |
| ? v => adder.add(+v || 0) |
| : v => adder.add(+valueof(v, ++index, values) || 0) |
| ); |
| } |
|
|