mirror of
https://github.com/josdejong/mathjs.git
synced 2026-02-01 16:07:46 +00:00
Fixed #172: parser not being able to evaluate an exponent followed by a unary minus like 2^-3, and a transpose followed by an index like [3]'[1].
This commit is contained in:
parent
d83e5b8d43
commit
3276b036a6
@ -4,10 +4,12 @@ https://github.com/josdejong/mathjs
|
||||
|
||||
## not yet released, version 0.21.1
|
||||
|
||||
- Fixed function `add` not adding strings and matrices element wise.
|
||||
- Removed `crypto` library from the bundle.
|
||||
- Deprecated functions `Parser.parse` and `Parser.compile`. Use
|
||||
`math.parse` and `math.compile` instead.
|
||||
- Fixed function `add` not adding strings and matrices element wise.
|
||||
- Fixed parser not being able to evaluate an exponent followed by a unary minus
|
||||
like `2^-3`, and a transpose followed by an index like `[3]'[1]`.
|
||||
|
||||
|
||||
## 2014-04-24, version 0.21.0
|
||||
|
||||
@ -754,7 +754,7 @@ function parseMultiplyDivide () {
|
||||
}
|
||||
|
||||
/**
|
||||
* parse units like in '2i', '2 cm'
|
||||
* parse units conversion 'in' like '5cm in inch'
|
||||
* @return {Node} node
|
||||
* @private
|
||||
*/
|
||||
@ -811,7 +811,7 @@ function parsePow () {
|
||||
fn = (name == '^') ? 'pow' : 'epow';
|
||||
|
||||
getToken();
|
||||
params = [node, parsePow()];
|
||||
params = [node, parseUnary()]; // Go back to unary, we can have '2^-3'
|
||||
node = new OperatorNode(name, fn, params);
|
||||
}
|
||||
|
||||
@ -841,6 +841,8 @@ function parseLeftHandOperators () {
|
||||
params = [node];
|
||||
|
||||
node = new OperatorNode(name, fn, params);
|
||||
|
||||
node = parseParams(node); // cases like "A'[2,3]"
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
@ -718,6 +718,17 @@ describe('parse', function() {
|
||||
approx.deepEqual(parseAndEval('2.54 cm in inch'), math.unit(1, 'inch').to('inch'));
|
||||
});
|
||||
|
||||
it('should parse ! (factorial)', function() {
|
||||
assert.deepEqual(parseAndEval('5!'), 120);
|
||||
assert.deepEqual(parseAndEval('[1,2,3,4]!'), new Matrix([1,2,6,24]));
|
||||
assert.deepEqual(parseAndEval('4!+2'), 26);
|
||||
assert.deepEqual(parseAndEval('4!-2'), 22);
|
||||
assert.deepEqual(parseAndEval('4!*2'), 48);
|
||||
assert.deepEqual(parseAndEval('3!!'), 720);
|
||||
assert.deepEqual(parseAndEval('[1,2;3,1]!\'!'), new Matrix([[1, 720], [2, 1]]));
|
||||
assert.deepEqual(parseAndEval('[2,3]![2]'), 6);
|
||||
});
|
||||
|
||||
it('should parse \' (transpose)', function() {
|
||||
assert.deepEqual(parseAndEval('23\''), 23);
|
||||
assert.deepEqual(parseAndEval('[1,2,3;4,5,6]\''), new Matrix([[1,4],[2,5],[3,6]]));
|
||||
@ -726,39 +737,73 @@ describe('parse', function() {
|
||||
assert.deepEqual(parseAndEval('[1:5]\''), new Matrix([[1],[2],[3],[4],[5]]));
|
||||
assert.deepEqual(parseAndEval('size([1:5])'), new Matrix([1, 5]));
|
||||
assert.deepEqual(parseAndEval('[1,2;3,4]\''), new Matrix([[1,3],[2,4]]));
|
||||
assert.deepEqual(parseAndEval('[1,2;3,4]\'[1,2]'), 3);
|
||||
});
|
||||
|
||||
it('should respect operator precedence', function() {
|
||||
assert.equal(parseAndEval('4-2+3'), 5);
|
||||
assert.equal(parseAndEval('4-(2+3)'), -1);
|
||||
assert.equal(parseAndEval('4-2-3'), -1);
|
||||
assert.equal(parseAndEval('4-(2-3)'), 5);
|
||||
describe('operator precedence', function() {
|
||||
it('should respect precedence of plus and minus', function () {
|
||||
assert.equal(parseAndEval('4-2+3'), 5);
|
||||
assert.equal(parseAndEval('4-(2+3)'), -1);
|
||||
assert.equal(parseAndEval('4-2-3'), -1);
|
||||
assert.equal(parseAndEval('4-(2-3)'), 5);
|
||||
});
|
||||
|
||||
assert.equal(parseAndEval('2+3*4'), 14);
|
||||
assert.equal(parseAndEval('2*3+4'), 10);
|
||||
assert.equal(parseAndEval('2*3^2'), 18);
|
||||
it('should respect precedence of plus/minus and multiply/divide', function () {
|
||||
assert.equal(parseAndEval('2+3*4'), 14);
|
||||
assert.equal(parseAndEval('2*3+4'), 10);
|
||||
});
|
||||
|
||||
assert.equal(parseAndEval('2^3'), 8);
|
||||
assert.equal(parseAndEval('2^3^4'), Math.pow(2, Math.pow(3, 4)));
|
||||
assert.equal(parseAndEval('1.5^1.5^1.5'), parseAndEval('1.5^(1.5^1.5)'));
|
||||
assert.equal(parseAndEval('1.5^1.5^1.5^1.5'), parseAndEval('1.5^(1.5^(1.5^1.5))'));
|
||||
it('should respect precedence of plus/minus and pow', function () {
|
||||
assert.equal(parseAndEval('2+3^2'), 11);
|
||||
assert.equal(parseAndEval('3^2+2'), 11);
|
||||
assert.equal(parseAndEval('8-2^2'), 4);
|
||||
assert.equal(parseAndEval('4^2-2'), 14);
|
||||
});
|
||||
|
||||
assert.equal(parseAndEval('-3^2'), -9);
|
||||
assert.equal(parseAndEval('(-3)^2'), 9);
|
||||
it('should respect precedence of multiply/divide and pow', function () {
|
||||
assert.equal(parseAndEval('2*3^2'), 18);
|
||||
assert.equal(parseAndEval('3^2*2'), 18);
|
||||
assert.equal(parseAndEval('8/2^2'), 2);
|
||||
assert.equal(parseAndEval('4^2/2'), 8);
|
||||
});
|
||||
|
||||
assert.equal(parseAndEval('2^3!'), 64);
|
||||
assert.equal(parseAndEval('2^(3!)'), 64);
|
||||
it('should respect precedence of pow', function () {
|
||||
assert.equal(parseAndEval('2^3'), 8);
|
||||
assert.equal(parseAndEval('2^3^4'), Math.pow(2, Math.pow(3, 4)));
|
||||
assert.equal(parseAndEval('1.5^1.5^1.5'), parseAndEval('1.5^(1.5^1.5)'));
|
||||
assert.equal(parseAndEval('1.5^1.5^1.5^1.5'), parseAndEval('1.5^(1.5^(1.5^1.5))'));
|
||||
});
|
||||
|
||||
assert.equal(parseAndEval('-4!'), -24);
|
||||
assert.equal(parseAndEval('3!+2'), 8);
|
||||
it('should respect precedence of unary minus and pow', function () {
|
||||
assert.equal(parseAndEval('-3^2'), -9);
|
||||
assert.equal(parseAndEval('(-3)^2'), 9);
|
||||
assert.equal(parseAndEval('2^-2'), 0.25);
|
||||
});
|
||||
|
||||
assert.equal(parseAndEval('2 > 3 ? true : false'), false);
|
||||
assert.equal(parseAndEval('2 == 3 ? true : false'), false);
|
||||
assert.equal(parseAndEval('3 ? 2 + 4 : 2 - 1'), 6);
|
||||
assert.deepEqual(parseAndEval('3 ? true : false; 22'), [22]);
|
||||
assert.deepEqual(parseAndEval('3 ? 5cm to m : 5cm in mm'), new Unit(5, 'cm').to('m'));
|
||||
assert.deepEqual(parseAndEval('2 == 4-2 ? [1,2] : false'), new Matrix([1,2]));
|
||||
assert.deepEqual(parseAndEval('false ? 1:2:6'), new Matrix([2,3,4,5,6]));
|
||||
it('should respect precedence of factorial and pow', function () {
|
||||
assert.equal(parseAndEval('2^3!'), 64);
|
||||
assert.equal(parseAndEval('2^(3!)'), 64);
|
||||
assert.equal(parseAndEval('3!^2'), 36);
|
||||
});
|
||||
|
||||
it('should respect precedence of factorial and (unary) plus/minus', function () {
|
||||
assert.equal(parseAndEval('-4!'), -24);
|
||||
assert.equal(parseAndEval('3!+2'), 8);
|
||||
});
|
||||
|
||||
it('should respect precedence of transpose', function () {
|
||||
// TODO: test transpose
|
||||
});
|
||||
|
||||
it('should respect precedence of conditional operator and other operators', function () {
|
||||
assert.equal(parseAndEval('2 > 3 ? true : false'), false);
|
||||
assert.equal(parseAndEval('2 == 3 ? true : false'), false);
|
||||
assert.equal(parseAndEval('3 ? 2 + 4 : 2 - 1'), 6);
|
||||
assert.deepEqual(parseAndEval('3 ? true : false; 22'), [22]);
|
||||
assert.deepEqual(parseAndEval('3 ? 5cm to m : 5cm in mm'), new Unit(5, 'cm').to('m'));
|
||||
assert.deepEqual(parseAndEval('2 == 4-2 ? [1,2] : false'), new Matrix([1,2]));
|
||||
assert.deepEqual(parseAndEval('false ? 1:2:6'), new Matrix([2,3,4,5,6]));
|
||||
});
|
||||
|
||||
// TODO: extensively test operator precedence
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user