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 <[email protected]> @@ -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 <[email protected]> Fri, 14 Aug 2015 11:04:30 +0200
-- Mailing list: https://launchpad.net/~ubuntu-touch-coreapps-reviewers Post to : [email protected] Unsubscribe : https://launchpad.net/~ubuntu-touch-coreapps-reviewers More help : https://help.launchpad.net/ListHelp

