mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
Fixed in mod for negative numerators. Added more input validation. Added tests
This commit is contained in:
parent
33bbd402b2
commit
0b2e28403b
@ -14,7 +14,8 @@ https://github.com/josdejong/mathjs
|
||||
- Moved the parse code from prototype math.expr.Parser to function math.parse,
|
||||
simplified Parser a little bit.
|
||||
- Strongly simplified the code of Scope and Workspace.
|
||||
- Minor bug fixes.
|
||||
- Fixed function mod for negative numerators, and added error messages in case
|
||||
of wrong input.
|
||||
|
||||
|
||||
## 2013-05-18, version 0.8.2
|
||||
|
||||
@ -723,6 +723,7 @@ Version 2.0:
|
||||
- A basic set of functions covering all common mathematical areas.
|
||||
- Functions and data types for numeral systems: Bin, Oct, Hex, Dec.
|
||||
- Arbitrary precision calculations with a BigNumber data type.
|
||||
- Support for derived units (like km/h, kg*m/s2, etc).
|
||||
|
||||
|
||||
## License
|
||||
|
||||
55
math.js
55
math.js
@ -7,7 +7,7 @@
|
||||
* mathematical functions, and a flexible expression parser.
|
||||
*
|
||||
* @version 0.8.3-SNAPSHOT
|
||||
* @date 2013-05-27
|
||||
* @date 2013-05-29
|
||||
*
|
||||
* @license
|
||||
* Copyright (C) 2013 Jos de Jong <wjosdejong@gmail.com>
|
||||
@ -5409,28 +5409,14 @@ math.mod = function mod(x, y) {
|
||||
throw newArgumentsError('mod', arguments.length, 2);
|
||||
}
|
||||
|
||||
// TODO: only handle integer values in mod?
|
||||
if (isNumber(x)) {
|
||||
if (isNumber(y)) {
|
||||
// number % number
|
||||
return x % y;
|
||||
}
|
||||
else if (y instanceof Complex && y.im == 0) {
|
||||
// number % complex
|
||||
return x % y.re;
|
||||
}
|
||||
}
|
||||
else if (x instanceof Complex && x.im == 0) {
|
||||
if (isNumber(y)) {
|
||||
// complex * number
|
||||
return x.re % y;
|
||||
}
|
||||
else if (y instanceof Complex && y.im == 0) {
|
||||
// complex * complex
|
||||
return x.re % y.re;
|
||||
}
|
||||
// see http://functions.wolfram.com/IntegerFunctions/Mod/
|
||||
|
||||
if (isNumber(x) && isNumber(y)) {
|
||||
// number % number
|
||||
return _mod(x, y);
|
||||
}
|
||||
|
||||
// TODO: implement mod for complex values
|
||||
|
||||
if (x instanceof Array || x instanceof Matrix ||
|
||||
y instanceof Array || y instanceof Matrix) {
|
||||
@ -5445,6 +5431,33 @@ math.mod = function mod(x, y) {
|
||||
throw newUnsupportedTypeError('mod', x, y);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the modulus of two numbers
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @returns {number} res
|
||||
* @private
|
||||
*/
|
||||
function _mod(x, y) {
|
||||
if (y > 0) {
|
||||
if (x > 0) {
|
||||
return x % y;
|
||||
}
|
||||
else if (x == 0) {
|
||||
return 0;
|
||||
}
|
||||
else { // x < 0
|
||||
return x - y * Math.floor(x / y);
|
||||
}
|
||||
}
|
||||
else if (y == 0) {
|
||||
return x;
|
||||
}
|
||||
else { // y < 0
|
||||
// TODO: implement mod for a negative divisor
|
||||
throw new Error('Cannot calculate mod for a negative divisor');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Multiply two values.
|
||||
*
|
||||
|
||||
8
math.min.js
vendored
8
math.min.js
vendored
File diff suppressed because one or more lines are too long
@ -15,28 +15,14 @@ math.mod = function mod(x, y) {
|
||||
throw newArgumentsError('mod', arguments.length, 2);
|
||||
}
|
||||
|
||||
// TODO: only handle integer values in mod?
|
||||
if (isNumber(x)) {
|
||||
if (isNumber(y)) {
|
||||
// number % number
|
||||
return x % y;
|
||||
}
|
||||
else if (y instanceof Complex && y.im == 0) {
|
||||
// number % complex
|
||||
return x % y.re;
|
||||
}
|
||||
}
|
||||
else if (x instanceof Complex && x.im == 0) {
|
||||
if (isNumber(y)) {
|
||||
// complex * number
|
||||
return x.re % y;
|
||||
}
|
||||
else if (y instanceof Complex && y.im == 0) {
|
||||
// complex * complex
|
||||
return x.re % y.re;
|
||||
}
|
||||
// see http://functions.wolfram.com/IntegerFunctions/Mod/
|
||||
|
||||
if (isNumber(x) && isNumber(y)) {
|
||||
// number % number
|
||||
return _mod(x, y);
|
||||
}
|
||||
|
||||
// TODO: implement mod for complex values
|
||||
|
||||
if (x instanceof Array || x instanceof Matrix ||
|
||||
y instanceof Array || y instanceof Matrix) {
|
||||
@ -50,3 +36,31 @@ math.mod = function mod(x, y) {
|
||||
|
||||
throw newUnsupportedTypeError('mod', x, y);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the modulus of two numbers
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @returns {number} res
|
||||
* @private
|
||||
*/
|
||||
function _mod(x, y) {
|
||||
if (y > 0) {
|
||||
if (x > 0) {
|
||||
return x % y;
|
||||
}
|
||||
else if (x == 0) {
|
||||
return 0;
|
||||
}
|
||||
else { // x < 0
|
||||
return x - y * Math.floor(x / y);
|
||||
}
|
||||
}
|
||||
else if (y == 0) {
|
||||
return x;
|
||||
}
|
||||
else { // y < 0
|
||||
// TODO: implement mod for a negative divisor
|
||||
throw new Error('Cannot calculate mod for a negative divisor');
|
||||
}
|
||||
}
|
||||
@ -1,2 +1,39 @@
|
||||
// test mod
|
||||
var assert = require('assert'),
|
||||
approx = require('../../../tools/approx.js'),
|
||||
math = require('../../../math.js'),
|
||||
matrix = math.matrix,
|
||||
range = math.range,
|
||||
mod = math.mod;
|
||||
|
||||
// TODO: test mod
|
||||
// test parser
|
||||
approx.equal(math.eval('8 % 3'), 2);
|
||||
approx.equal(math.eval('mod(8, 3)'), 2);
|
||||
|
||||
// test number
|
||||
approx.equal(mod(7, 2), 1);
|
||||
approx.equal(mod(9, 3), 0);
|
||||
approx.equal(mod(10, 4), 2);
|
||||
assert.throws(function () {mod(10, -4)});
|
||||
approx.equal(mod(-10, 4), 2);
|
||||
assert.throws(function () {mod(-10, -4)});
|
||||
approx.equal(mod(8.2, 3), 2.2);
|
||||
approx.equal(mod(4, 1.5), 1);
|
||||
approx.equal(mod(0, 3), 0);
|
||||
|
||||
// test wrong number of arguments
|
||||
assert.throws(function () {mod(1)}, SyntaxError);
|
||||
assert.throws(function () {mod(1,2,3)}, SyntaxError);
|
||||
|
||||
// test complex
|
||||
assert.throws(function () {mod(math.complex(1,2), 3)}, TypeError);
|
||||
assert.throws(function () {mod(3, math.complex(1,2))}, TypeError);
|
||||
|
||||
// test string
|
||||
assert.throws(function () {mod('string', 3)}, TypeError);
|
||||
assert.throws(function () {mod(5, 'string')}, TypeError);
|
||||
|
||||
// test array, matrix, range
|
||||
approx.deepEqual(mod([-4,-3,-2,-1,0,1,2,3,4], 3), [2,0,1,2,0,1,2,0,1]);
|
||||
approx.deepEqual(mod(matrix([-4,-3,-2,-1,0,1,2,3,4]), 3), matrix([2,0,1,2,0,1,2,0,1]));
|
||||
approx.deepEqual(mod(range(-4,4), 3), [2,0,1,2,0,1,2,0,1]);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// TODO: test subset
|
||||
// test subset
|
||||
var assert = require('assert'),
|
||||
math = require('../../../math.js'),
|
||||
subset = math.subset,
|
||||
@ -128,7 +128,7 @@ assert.deepEqual(parser.eval('a(:,2)'), matrix([[2],[4]]));
|
||||
assert.deepEqual(parser.eval('a(:,2) = [-2;-4]'), matrix([[1,-2],[3,-4]]));
|
||||
assert.deepEqual(parser.eval('b=123'), 123);
|
||||
assert.deepEqual(parser.eval('b(1)'), 123);
|
||||
// assert.deepEqual(parser.eval('b(1,1)'), 123); // TODO: should be supported
|
||||
// assert.deepEqual(parser.eval('b(1,1)'), 123); // TODO: should be supported?
|
||||
assert.deepEqual(parser.eval('b(1)=456'), 456);
|
||||
assert.deepEqual(parser.eval('b'), 456);
|
||||
assert.deepEqual(parser.eval('c="hello"'), "hello");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user