ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #05674
[Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2.4.1 into lp:ubuntu-calculator-app
Bartosz Kosiorek has proposed merging lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2.4.1 into lp:ubuntu-calculator-app.
Commit message:
Upgrade math.js to 2.4.1 to fix crash with factorial (LP: #1483600)
Requested reviews:
Ubuntu Calculator Developers (ubuntu-calculator-dev)
Related bugs:
Bug #1483600 in Ubuntu Calculator App: "The calculator will exit automaticlly when calculating result is too large "
https://bugs.launchpad.net/ubuntu-calculator-app/+bug/1483600
For more details, see:
https://code.launchpad.net/~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2.4.1/+merge/276316
Upgrade math.js to 2.4.1 to fix crash with factorial (LP: #1483600)
--
Your team Ubuntu Calculator Developers is requested to review the proposed merge of lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2.4.1 into lp:ubuntu-calculator-app.
=== modified file 'app/engine/math.js'
--- app/engine/math.js 2015-10-19 22:33:25 +0000
+++ app/engine/math.js 2015-10-30 20:23:23 +0000
@@ -14,8 +14,8 @@
* It features real and complex numbers, units, matrices, a large set of
* mathematical functions, and a flexible expression parser.
*
- * @version 2.4.0
- * @date 2015-10-09
+ * @version 2.4.1
+ * @date 2015-10-29
*
* @license
* Copyright (C) 2013-2015 Jos de Jong <wjosdejong@xxxxxxxxx>
@@ -35,8 +35,7 @@
(function webpackUniversalModuleDefinition(root, factory) {
// UCA: we delete all exports, we don't need them, and we keep only our var
- mathJs = factory();
-})(this, function() {
+ mathJs = factory();})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
@@ -2628,6 +2627,7 @@
if (isFactory(object)) {
_importFactory(object, options);
}
+ // TODO: allow a typed-function with name too
else if (Array.isArray(object)) {
object.forEach(function (entry) {
math_import(entry, options);
@@ -2671,11 +2671,12 @@
}
if (isTypedFunction(math[name]) && isTypedFunction(value)) {
- // merge two typed functions
if (options.override) {
- value = typed(extend({}, math[name].signatures, value.signatures));
+ // give the typed function the right name
+ value = typed(name, value.signatures);
}
else {
+ // merge the existing and typed function
value = typed(math[name], value);
}
@@ -2747,11 +2748,11 @@
var instance = load(factory);
if (isTypedFunction(existing) && isTypedFunction(instance)) {
- // merge two typed functions
if (options.override) {
- instance = typed(extend({}, existing.signatures, instance.signatures));
+ // replace the existing typed function (nothing to do)
}
else {
+ // merge the existing and new typed function
instance = typed(existing, instance);
}
@@ -13692,7 +13693,7 @@
this._values = [];
this._index = [];
this._ptr = [0];
- this._size = [0];
+ this._size = [0, 0];
this._datatype = datatype;
}
}
@@ -18688,7 +18689,7 @@
/* 79 */
/***/ function(module, exports) {
- module.exports = '2.4.0';
+ module.exports = '2.4.1';
// Note: This file is automatically generated when building math.js.
// Changes made in this file will be overwritten.
@@ -20851,16 +20852,15 @@
'name': 'not',
'category': 'Logical',
'syntax': [
- '!x',
'not x',
'not(x)'
],
'description': 'Logical not. Flips the boolean value of given argument.',
'examples': [
- '!true',
+ 'not true',
'not false',
- '!2',
- '!0'
+ 'not 2',
+ 'not 0'
],
'seealso': [
'and', 'or', 'xor'
@@ -39264,37 +39264,36 @@
* @private
*/
function _bigNthRoot(a, root) {
+ var precision = type.BigNumber.precision;
+ var Big = type.BigNumber.constructor({precision: precision + 2});
var zero = new type.BigNumber(0);
- var one = new type.BigNumber(1);
+
+ var one = new Big(1);
var inv = root.isNegative();
- if (inv) root = root.negated();
+ if (inv) {
+ root = root.neg();
+ }
- if (root.isZero()) throw new Error('Root must be non-zero');
- if (a.isNegative() && !root.abs().mod(2).equals(1)) throw new Error('Root must be odd when a is negative.');
+ if (root.isZero()) {
+ throw new Error('Root must be non-zero');
+ }
+ if (a.isNegative() && !root.abs().mod(2).equals(1)) {
+ throw new Error('Root must be odd when a is negative.');
+ }
// edge cases zero and infinity
- if (a.isZero()) return zero;
- if (!a.isFinite())
- {
+ if (a.isZero()) {
+ return zero;
+ }
+ if (!a.isFinite()) {
return inv ? zero : a;
}
- var x = one; // Initial guess
- var i = 0;
- var iMax = 10000;
- do {
- var xPrev = x;
- var delta = a.div(x.pow(root.minus(1))).minus(x).div(root);
- x = x.plus(delta);
- i++;
- }
- while (!x.equals(xPrev) && i < iMax);
-
- if (!x.equals(xPrev)) {
- throw new Error('Function nthRoot failed to converge');
- }
-
- return inv ? one.div(x) : x;
+ var x = a.abs().pow(one.div(root));
+ // If a < 0, we require that root is an odd integer,
+ // so (-1) ^ (1/root) = -1
+ x = a.isNeg() ? x.neg() : x;
+ return new type.BigNumber((inv ? one.div(x) : x).toPrecision(precision));
}
}
@@ -39307,17 +39306,35 @@
*/
function _nthRoot(a, root) {
var inv = root < 0;
- if (inv) root = -root;
+ if (inv) {
+ root = -root;
+ }
- if (root === 0) throw new Error('Root must be non-zero');
- if (a < 0 && (Math.abs(root) % 2 != 1)) throw new Error('Root must be odd when a is negative.');
+ if (root === 0) {
+ throw new Error('Root must be non-zero');
+ }
+ if (a < 0 && (Math.abs(root) % 2 != 1)) {
+ throw new Error('Root must be odd when a is negative.');
+ }
// edge cases zero and infinity
- if (a == 0) return 0;
- if (!Number.isFinite(a)) {
+ if (a == 0) {
+ return 0;
+ }
+ if (!isFinite(a)) {
return inv ? 0 : a;
}
+ var x = Math.pow(Math.abs(a), 1/root);
+ // If a < 0, we require that root is an odd integer,
+ // so (-1) ^ (1/root) = -1
+ x = a < 0 ? -x : x;
+ return inv ? 1 / x : x;
+
+ // Very nice algorithm, but fails with nthRoot(-2, 3).
+ // Newton's method has some well-known problems at times:
+ // https://en.wikipedia.org/wiki/Newton%27s_method#Failure_analysis
+ /*
var x = 1; // Initial guess
var xPrev = 1;
var i = 0;
@@ -39335,6 +39352,7 @@
}
return inv ? 1 / x : x;
+ */
}
/**
@@ -42075,39 +42093,21 @@
* @returns {BigNumber} Returns the factorial of n
*/
function bigFactorial(n) {
- var value, res, preciseFacs;
-
- var num = n.toNumber(); // should definitely be below Number.MAX_VALUE
- if (num < smallBigFacs.length) {
- return new type.BigNumber(smallBigFacs[num]).toSD(config.precision);
+ if (n.isZero()) {
+ return new type.BigNumber(1); // 0! is per definition 1
}
- // be wary of round-off errors
- var precision = config.precision + (Math.log(num) | 0);
+ var precision = config.precision + (Math.log(n.toNumber()) | 0);
var Big = type.BigNumber.constructor({precision: precision});
- // adjust n do align with the precision specific tables
- num -= smallBigFacs.length;
- if (preciseFacs = bigBigFacs[precision]) {
- if (preciseFacs[num]) {
- return new type.BigNumber(preciseFacs[num].toPrecision(config.precision));
- }
- res = preciseFacs[preciseFacs.length-1];
- } else {
- preciseFacs = bigBigFacs[precision] = [];
- res = new Big(smallBigFacs[smallBigFacs.length-1])
- .toSD(precision);
- }
-
- var one = new Big(1);
- value = new Big(preciseFacs.length + smallBigFacs.length);
- for (var i = preciseFacs.length; i < num; ++i) {
- preciseFacs[i] = res = res.times(value);
- value = value.plus(one);
- }
-
- preciseFacs[num] = res.times(value);
- return new type.BigNumber(preciseFacs[num].toPrecision(config.precision));
+ var res = new Big(n);
+ var value = n.toNumber() - 1; // number
+ while (value > 1) {
+ res = res.times(value);
+ value--;
+ }
+
+ return new type.BigNumber(res.toPrecision(type.BigNumber.precision));
}
gamma.toTex = '\\Gamma\\left(${args[0]}\\right)';
@@ -42137,34 +42137,6 @@
0.36899182659531622704e-5
];
- // 21! >= values for each precision
- var bigBigFacs = [];
-
- // 0-20! values
- var smallBigFacs = [
- 1,
- 1,
- 2,
- 6,
- 24,
- 120,
- 720,
- 5040,
- 40320,
- 362880,
- 3628800,
- 39916800,
- 479001600,
- 6227020800,
- 87178291200,
- 1307674368000,
- 20922789888000,
- 355687428096000,
- 6402373705728000,
- 121645100408832000,
- 2432902008176640000
- ];
-
exports.name = 'gamma';
exports.factory = factory;
@@ -42208,6 +42180,9 @@
if (!isInteger(n) || n < 0) {
throw new TypeError('Positive integer value expected in function combinations');
}
+ if (!isInteger(k) || k < 0) {
+ throw new TypeError('Positive integer value expected in function combinations');
+ }
if (k > n) {
throw new TypeError('k must be less than or equal to n');
}
=== modified file 'debian/changelog'
--- debian/changelog 2015-10-19 22:36:57 +0000
+++ debian/changelog 2015-10-30 20:23:23 +0000
@@ -27,6 +27,7 @@
* Upgrade math.js to 2.1.1 to improve performance (LP: #1484851)
* Upgrade math.js to 2.4.0 to resolve wrong calculation of sin and cos functions,
for values around multiples of tau (i.e. sin(7)) (LP: #1507799)
+ * Upgrade math.js to 2.4.1 to fix crash with factorial (LP: #1483600)
-- Bartosz Kosiorek <gang65@xxxxxxxxxxxxxx> Fri, 14 Aug 2015 11:04:30 +0200
Follow ups