diff --git a/decimal.js b/decimal.js index 511028e..e58df57 100644 --- a/decimal.js +++ b/decimal.js @@ -2629,9 +2629,9 @@ */ function cosine(Ctor, x) { var k, len, y; - + if (x.isZero()) return x; - + // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 @@ -3665,10 +3665,10 @@ function sine(Ctor, x) { var k, len = x.d.length; - + if (len < 3) { return x.isZero() ? x : taylorSeries(Ctor, 2, x, x); - } + } // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) @@ -3959,6 +3959,7 @@ * sinh * sqrt * sub + * sum * tan * tanh * trunc @@ -4407,6 +4408,7 @@ Decimal.sinh = sinh; // ES6 Decimal.sqrt = sqrt; Decimal.sub = sub; + Decimal.sum = sum; Decimal.tan = tan; Decimal.tanh = tanh; // ES6 Decimal.trunc = trunc; // ES6 @@ -4801,6 +4803,28 @@ } + /* + * Return a new Decimal whose value is the sum of the arguments, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * Only the result is rounded, not the intermediate calculations. + * + * arguments {number|string|Decimal} + * + */ + function sum() { + var i = 0, + args = arguments, + x = new this(args[i]); + + external = false; + for (; x.s && ++i < args.length;) x = x.plus(args[i]); + external = true; + + return finalise(x, this.precision, this.rounding); + } + + /* * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant * digits using rounding mode `rounding`. diff --git a/decimal.mjs b/decimal.mjs index 81b7086..a319764 100644 --- a/decimal.mjs +++ b/decimal.mjs @@ -2624,13 +2624,15 @@ function convertBase(str, baseIn, baseOut) { * */ function cosine(Ctor, x) { - var k, y, - len = x.d.length; + var k, len, y; + + if (x.isZero()) return x; // Argument reduction: cos(4x) = 8*(cos^4(x) - cos^2(x)) + 1 // i.e. cos(x) = 8*(cos^4(x/4) - cos^2(x/4)) + 1 // Estimate the optimum number of times to use the argument reduction. + len = x.d.length; if (len < 32) { k = Math.ceil(len / 3); y = (1 / tinyPow(4, k)).toString(); @@ -3660,7 +3662,9 @@ function sine(Ctor, x) { var k, len = x.d.length; - if (len < 3) return taylorSeries(Ctor, 2, x, x); + if (len < 3) { + return x.isZero() ? x : taylorSeries(Ctor, 2, x, x); + } // Argument reduction: sin(5x) = 16*sin^5(x) - 20*sin^3(x) + 5*sin(x) // i.e. sin(x) = 16*sin^5(x/5) - 20*sin^3(x/5) + 5*sin(x/5) @@ -3951,6 +3955,7 @@ function truncate(arr, len) { * sinh * sqrt * sub + * sum * tan * tanh * trunc @@ -4399,6 +4404,7 @@ function clone(obj) { Decimal.sinh = sinh; // ES6 Decimal.sqrt = sqrt; Decimal.sub = sub; + Decimal.sum = sum; Decimal.tan = tan; Decimal.tanh = tanh; // ES6 Decimal.trunc = trunc; // ES6 @@ -4793,6 +4799,28 @@ function sub(x, y) { } +/* + * Return a new Decimal whose value is the sum of the arguments, rounded to `precision` + * significant digits using rounding mode `rounding`. + * + * Only the result is rounded, not the intermediate calculations. + * + * arguments {number|string|Decimal} + * + */ +function sum() { + var i = 0, + args = arguments, + x = new this(args[i]); + + external = false; + for (; x.s && ++i < args.length;) x = x.plus(args[i]); + external = true; + + return finalise(x, this.precision, this.rounding); +} + + /* * Return a new Decimal whose value is the tangent of `x`, rounded to `precision` significant * digits using rounding mode `rounding`. diff --git a/doc/API.html b/doc/API.html index 9eb8e14..7af7e90 100644 --- a/doc/API.html +++ b/doc/API.html @@ -102,6 +102,7 @@ li span{float:right;margin-right:10px;color:#c0c0c0}
.max([x [, y, ...]]) ⇒ Decimal
+ max.max(x [, y, ...]) ⇒ Decimal
x
: number|string|Decimal
@@ -613,7 +614,7 @@ a.equals(b) // true
.min([x [, y, ...]]) ⇒ Decimal
+ min.min(x [, y, ...]) ⇒ Decimal
x
: number|string|Decimal
@@ -833,7 +834,7 @@ a.equals(b) // true
-
.sub(x, y) ⇒ Decimal
.sub(x, y) ⇒ Decimal
x
: number|string|Decimal
y
: number|string|Decimal
@@ -845,7 +846,26 @@ a.equals(b) // true
-
.tan(x) ⇒ Decimal
.sum(x [, y, ...]) ⇒ Decimal
+ x
: number|string|Decimal
+ y
: number|string|Decimal
+
+ Returns a new Decimal whose value is the sum of the arguments
,
+ rounded to precision
significant digits using
+ rounding mode rounding
.
+ Only the result is rounded, not the intermediate summations.
+
+x = 5 +y = '16' +z = new Decimal(-11) +Decimal.sum(x, y, z) // '10'+ + + +
.tan(x) ⇒ Decimal
x
: number|string|Decimal
See tangent
.
a = Decimal.tan(x) diff --git a/test/modules/sum.js b/test/modules/sum.js new file mode 100644 index 0000000..6dda6f0 --- /dev/null +++ b/test/modules/sum.js @@ -0,0 +1,64 @@ +if (typeof T === 'undefined') require('../setup'); + +T('sum', function () { + var expected; + + function t() { + T.assertEqualDecimal(expected, Decimal.sum.apply(Decimal, arguments)); + } + + expected = new Decimal(0); + + t('0'); + t('0', new Decimal(0)); + t(1, 0, '-1'); + t(0, new Decimal('-10'), 0, 0, 0, 0, 0, 10); + t(11, -11); + t(1, '2', new Decimal(3), new Decimal('4'), -10); + t(new Decimal(-10), '9', new Decimal(0.01), 0.99); + + expected = new Decimal(10); + + t('10'); + t('0', new Decimal('10')); + t(10, 0); + t(0, 0, 0, 0, 0, 0, 10); + t(11, -1); + t(1, '2', new Decimal(3), new Decimal('4')); + t('9', new Decimal(0.01), 0.99); + + expected = new Decimal(600); + + t(100, 200, 300); + t('100', '200', '300'); + t(new Decimal(100), new Decimal(200), new Decimal(300)); + t(100, '200', new Decimal(300)); + t(99.9, 200.05, 300.05); + + expected = new Decimal(NaN); + + t(NaN); + t('1', NaN); + t(100, 200, NaN); + t(NaN, 0, '9', new Decimal(0), 11, Infinity); + t(0, new Decimal('-Infinity'), '9', new Decimal(NaN), 11); + t(4, '-Infinity', 0, '9', new Decimal(0), Infinity, 2); + + expected = new Decimal(Infinity); + + t(Infinity); + t(1, '1e10000000000000000000000000000000000000000', '4'); + t(100, 200, 'Infinity'); + t(0, new Decimal('Infinity'), '9', new Decimal(0), 11); + t(0, '9', new Decimal(0), 11, Infinity); + t(4, new Decimal(Infinity), 0, '9', new Decimal(0), Infinity, 2); + + expected = new Decimal(-Infinity); + + t(-Infinity); + t(1, '-1e10000000000000000000000000000000000000000', '4'); + t(100, 200, '-Infinity'); + t(0, new Decimal('-Infinity'), '9', new Decimal(0), 11); + t(0, '9', new Decimal(0), 11, -Infinity); + t(4, new Decimal(-Infinity), 0, '9', new Decimal(0), -Infinity, 2); +}); \ No newline at end of file diff --git a/test/test.html b/test/test.html index fd07521..7412f16 100644 --- a/test/test.html +++ b/test/test.html @@ -59,6 +59,7 @@ 'sin', 'sinh', 'sqrt', + 'sum', 'tan', 'tanh', 'times', diff --git a/test/test.js b/test/test.js index cdf4aca..bcc42f4 100644 --- a/test/test.js +++ b/test/test.js @@ -46,6 +46,7 @@ console.log('\n Testing decimal.js\n'); 'sin', 'sinh', 'sqrt', + 'sum', 'tan', 'tanh', 'times',