├── README.md ├── index.js ├── package.json └── test └── test.sum.js /README.md: -------------------------------------------------------------------------------- 1 | Kahan summation algorithm for Node.js 2 | ===================================== 3 | 4 | Since JavaScript's only numerical data type is Number, internally represented 5 | as floating-point number, calculating a sum of numbers can introduce significant 6 | numerical error. This library aims to reduce the error by employing 7 | [Kahan's summation algorithm](http://en.wikipedia.org/wiki/Kahan_summation_algorithm). 8 | 9 | Example 10 | ------- 11 | 12 | ```js 13 | // Naive summation 14 | [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7].reduce(function(a, b) { return a + b }) 15 | // -> 15.299999999999999 16 | 17 | // Kahan summation 18 | require('kahan').sum([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7]) 19 | // -> 15.3 20 | ``` 21 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // Implements http://en.wikipedia.org/wiki/Kahan_summation_algorithm 2 | 3 | function kahanSum(inputArray) { 4 | var sum = 0.0 5 | , c = 0.0 // A running compensation for lost low-order bits. 6 | for(var i = 0; i < inputArray.length; i++) { 7 | y = inputArray[i] - c // So far, so good: c is zero. 8 | t = sum + y // Alas, sum is big, y small, so low-order digits of y are lost. 9 | c = (t - sum) - y // (t - sum) recovers the high-order part of y; subtracting y recovers -(low part of y) 10 | sum = t // Algebraically, c should always be zero. Beware eagerly optimising compilers! 11 | } // Next time around, the lost low part will be added to y in a fresh attempt. 12 | return sum 13 | } 14 | 15 | module.exports = { 16 | sum: kahanSum 17 | } 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kahan", 3 | "version": "0.0.3", 4 | "description": "Kahan summation algorithm for node.js", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/viktors/node-kahan.git" 8 | }, 9 | "author": "Viktors Rotanovs (http://rotanovs.com)", 10 | "dependencies": { 11 | "expresso": ">=0.7.7" 12 | }, 13 | "main": "index", 14 | "engines": { 15 | "node": ">= 0.4.0 < 0.5.0" 16 | }, 17 | "files": [ 18 | "" 19 | ], 20 | "devDependencies": {} 21 | } -------------------------------------------------------------------------------- /test/test.sum.js: -------------------------------------------------------------------------------- 1 | // Run $ expresso 2 | 3 | var assert = require('assert'), 4 | kahan = require('../index.js') 5 | 6 | var testArray = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7] 7 | 8 | module.exports = 9 | { 'test naive summation': function() { assert.equal(15.299999999999999, testArray.reduce(function(a, b) { return a + b })) } 10 | , 'test Kahan summation': function() { assert.equal(15.3, kahan.sum(testArray)) } 11 | } 12 | --------------------------------------------------------------------------------