Skip to content

Instantly share code, notes, and snippets.

@1st1
Created December 11, 2014 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1st1/1199936ef171a3696886 to your computer and use it in GitHub Desktop.
Save 1st1/1199936ef171a3696886 to your computer and use it in GitHub Desktop.
Binary floating point summation accurate to full precision in JavaScript
// Read this first: http://code.activestate.com/recipes/393090/
function sum(ar) {
var c = ar.length;
var s = 0;
for (var i = 0; i < c; i++) {
s += ar[i];
}
return s;
}
function msum(ar) {
var partials = [], x, y, j, k, i, tmp, hi, lo;
for (j = 0; j < ar.length; j++) {
x = ar[j];
i = 0;
for (k = 0; k < partials.length; k++) {
y = partials[k];
if (Math.abs(x) < Math.abs(y)) {
tmp = x;
x = y;
y = tmp;
}
hi = x + y;
lo = y - (hi - x);
if (lo) {
partials[i] = lo;
i++;
}
x = hi;
}
if (partials.length > i) {
partials.length = i;
}
partials.push(x);
}
var sum = 0.0;
for (i = 0; i < partials.length; i++) {
sum += partials[i];
}
return sum;
}
console.log('3 =', msum([1,2]), '=', sum([1,2]))
console.log('6 =', msum([1,2,3]), '=', sum([1,2,3]))
console.log('10 =', msum([1,2,3,4]), '=', sum([1,2,3,4]))
var a = [], i;
for (i = 0; i < 10000; i++) a.push(1, 1e100, 1, -1e100);
console.log('2 =', msum([1, 1e100, 1, -1e100]), '=', sum([1, 1e100, 1, -1e100]));
console.log('20000 =', msum(a), '=', sum(a));
@1st1
Copy link
Author

1st1 commented Dec 11, 2014

Example output:

3 = 3 = 3
6 = 6 = 6
10 = 10 = 10
2 = 2 = 0
20000 = 20000 = 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment