|
|
|
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) |
|
); |
|
} |
|
|