Comparing version 2.0.5 to 2.0.6
264
index.js
@@ -1,157 +0,177 @@ | ||
// The minimum machine rounding error | ||
var Epsilon = Math.pow(2, -53) | ||
, EpsilonReciprocal = (1 / Epsilon) | ||
/// The smallest positive number that can be represented | ||
, Eta = Math.pow(2, -1074) | ||
// limitB is a constant used in the transform function | ||
, limitB = 0.5 * EpsilonReciprocal * Eta | ||
(function (root, factory) { | ||
"use strict"; | ||
/** | ||
* S. M. RUMP, T. OGITA AND S. OISHI | ||
* http://www.ti3.tu-harburg.de/paper/rump/RuOgOi07I.pdf | ||
*/ | ||
// AMD | ||
if (typeof define === 'function' && define.amd) { | ||
define([], factory); | ||
} | ||
// CommonJS | ||
else if (typeof exports === 'object') { | ||
module.exports = factory(); | ||
} | ||
// Browser | ||
else { | ||
root.add = factory(); | ||
} | ||
})(this, function () { | ||
"use strict"; | ||
// Page 8 | ||
// x is result, y is error | ||
// third is so the array is allocated for 4 spaces | ||
// it speeds up transform | ||
function fastTwoSum(a, b) { | ||
var x = a + b | ||
, q = x - a | ||
, y = b - q | ||
// The minimum machine rounding error | ||
var Epsilon = Math.pow(2, -53) | ||
, EpsilonReciprocal = (1 / Epsilon) | ||
/// The smallest positive number that can be represented | ||
, Eta = Math.pow(2, -1074) | ||
// limitB is a constant used in the transform function | ||
, limitB = 0.5 * EpsilonReciprocal * Eta | ||
return [x, y, null] | ||
} | ||
/** | ||
* S. M. RUMP, T. OGITA AND S. OISHI | ||
* http://www.ti3.tu-harburg.de/paper/rump/RuOgOi07I.pdf | ||
*/ | ||
// Page 12 | ||
// p = q + p' | ||
// sigma is a power of 2 greater than or equal to |p| | ||
function extractScalar(sigma, p) { | ||
var q = (sigma + p) - sigma | ||
, pPrime = p - q | ||
// Page 8 | ||
// x is result, y is error | ||
// third is so the array is allocated for 4 spaces | ||
// it speeds up transform | ||
function fastTwoSum(a, b) { | ||
var x = a + b | ||
, q = x - a | ||
, y = b - q | ||
return [q, pPrime] | ||
} | ||
return [x, y, null] | ||
} | ||
// Page 12 | ||
function extractVector(sigma, p) { | ||
var tau = 0.0 | ||
, extracted | ||
, i = 0 | ||
, ii = p.length | ||
, pPrime = new Array(ii) | ||
// Page 12 | ||
// p = q + p' | ||
// sigma is a power of 2 greater than or equal to |p| | ||
function extractScalar(sigma, p) { | ||
var q = (sigma + p) - sigma | ||
, pPrime = p - q | ||
for(; i<ii; ++i) { | ||
extracted = extractScalar(sigma, p[i]) | ||
pPrime[i] = extracted[1] | ||
tau += extracted[0] | ||
return [q, pPrime] | ||
} | ||
return [tau, pPrime] | ||
} | ||
// Page 12 | ||
function extractVector(sigma, p) { | ||
var tau = 0.0 | ||
, extracted | ||
, i = 0 | ||
, ii = p.length | ||
, pPrime = new Array(ii) | ||
// Finds the immediate power of 2 that is larger than p | ||
//// in a fast way | ||
function nextPowerTwo (p) { | ||
var q = EpsilonReciprocal * p | ||
, L = Math.abs((q + p) - q) | ||
for(; i<ii; ++i) { | ||
extracted = extractScalar(sigma, p[i]) | ||
pPrime[i] = extracted[1] | ||
tau += extracted[0] | ||
} | ||
if(L === 0) | ||
return Math.abs(p) | ||
return [tau, pPrime] | ||
} | ||
return L | ||
} | ||
// Finds the immediate power of 2 that is larger than p | ||
//// in a fast way | ||
function nextPowerTwo (p) { | ||
var q = EpsilonReciprocal * p | ||
, L = Math.abs((q + p) - q) | ||
// Helper, gets the maximum of the absolute values of an array | ||
function maxAbs(arr) { | ||
var i = 0 | ||
, ii = arr.length | ||
, best = -1 | ||
if(L === 0) | ||
return Math.abs(p) | ||
for(; i<ii; ++i) { | ||
if(Math.abs(arr[i]) > best) { | ||
best = arr[i] | ||
return L | ||
} | ||
// Helper, gets the maximum of the absolute values of an array | ||
function maxAbs(arr) { | ||
var i = 0 | ||
, ii = arr.length | ||
, best = -1 | ||
for(; i<ii; ++i) { | ||
if(Math.abs(arr[i]) > best) { | ||
best = arr[i] | ||
} | ||
} | ||
return best | ||
} | ||
return best | ||
} | ||
function transform (p) { | ||
var mu = maxAbs(p) | ||
, M | ||
, sigmaPrime | ||
, tPrime | ||
, t | ||
, tau | ||
, sigma | ||
, extracted | ||
, res | ||
function transform (p) { | ||
var mu = maxAbs(p) | ||
, M | ||
, sigmaPrime | ||
, tPrime | ||
, t | ||
, tau | ||
, sigma | ||
, extracted | ||
, res | ||
// Not part of the original paper, here for optimization | ||
, temp | ||
, bigPow | ||
, limitA | ||
, twoToTheM | ||
// Not part of the original paper, here for optimization | ||
, temp | ||
, bigPow | ||
, limitA | ||
, twoToTheM | ||
if(mu === 0) { | ||
return [0, 0, p, 0] | ||
} | ||
if(mu === 0) { | ||
return [0, 0, p, 0] | ||
} | ||
M = nextPowerTwo(p.length + 2) | ||
twoToTheM = Math.pow(2, M) | ||
bigPow = 2 * twoToTheM // equiv to Math.pow(2, 2 * M), faster | ||
sigmaPrime = twoToTheM * nextPowerTwo(mu) | ||
tPrime = 0 | ||
M = nextPowerTwo(p.length + 2) | ||
twoToTheM = Math.pow(2, M) | ||
bigPow = 2 * twoToTheM // equiv to Math.pow(2, 2 * M), faster | ||
sigmaPrime = twoToTheM * nextPowerTwo(mu) | ||
tPrime = 0 | ||
do { | ||
t = tPrime | ||
sigma = sigmaPrime | ||
extracted = extractVector(sigma, p) | ||
tau = extracted[0] | ||
tPrime = t + tau | ||
p = extracted[1] | ||
do { | ||
t = tPrime | ||
sigma = sigmaPrime | ||
extracted = extractVector(sigma, p) | ||
tau = extracted[0] | ||
tPrime = t + tau | ||
p = extracted[1] | ||
if(tPrime === 0) { | ||
return transform(p) | ||
} | ||
if(tPrime === 0) { | ||
return transform(p) | ||
temp = Epsilon * sigma | ||
sigmaPrime = twoToTheM * temp | ||
limitA = bigPow * temp | ||
} | ||
while( Math.abs(tPrime) < limitA && sigma > limitB ) | ||
temp = Epsilon * sigma | ||
sigmaPrime = twoToTheM * temp | ||
limitA = bigPow * temp | ||
// res already allocated for 4 | ||
res = fastTwoSum(t, tau) | ||
res[2] = p | ||
return res | ||
} | ||
while( Math.abs(tPrime) < limitA && sigma > limitB ) | ||
// res already allocated for 4 | ||
res = fastTwoSum(t, tau) | ||
res[2] = p | ||
function dumbSum(p) { | ||
var i, ii, sum = 0.0 | ||
for(i=0, ii=p.length; i<ii; ++i) { | ||
sum += p[i] | ||
} | ||
return sum | ||
} | ||
return res | ||
} | ||
function accSum(p) { | ||
function dumbSum(p) { | ||
var i, ii, sum = 0.0 | ||
for(i=0, ii=p.length; i<ii; ++i) { | ||
sum += p[i] | ||
} | ||
return sum | ||
} | ||
// Zero length array, or all values are zeros | ||
if(p.length === 0 || maxAbs(p) === 0) { | ||
return 0 | ||
} | ||
function accSum(p) { | ||
var tfmd = transform(p) | ||
// Zero length array, or all values are zeros | ||
if(p.length === 0 || maxAbs(p) === 0) { | ||
return 0 | ||
return tfmd[0] + (tfmd[1] +dumbSum(tfmd[2])) | ||
} | ||
var tfmd = transform(p) | ||
return tfmd[0] + (tfmd[1] +dumbSum(tfmd[2])) | ||
} | ||
// exports | ||
accSum.dumbSum = dumbSum; | ||
accSum.fastTwoSum = fastTwoSum; | ||
accSum.nextPowerTwo = nextPowerTwo; | ||
return accSum; | ||
}); | ||
module.exports = accSum | ||
module.exports.dumbSum = dumbSum | ||
module.exports.fastTwoSum = fastTwoSum | ||
module.exports.nextPowerTwo = nextPowerTwo | ||
{ | ||
"name": "add", | ||
"version": "2.0.5", | ||
"version": "2.0.6", | ||
"description": "A cross-browser, numerically stable algorithm to add floats accurately", | ||
@@ -17,3 +17,3 @@ "main": "index.js", | ||
"faithful", | ||
"founding", | ||
"rounding", | ||
"float", | ||
@@ -40,4 +40,3 @@ "error", | ||
"iphone/6", | ||
"ipad/6", | ||
"android-browser/latest" | ||
"ipad/6" | ||
] | ||
@@ -44,0 +43,0 @@ }, |
8058
7
207