mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-18 14:59:29 +00:00
Implemented methods ceil, fix, floor, round, random, atan2
This commit is contained in:
parent
27b96f31e9
commit
16c64dffda
384
lib/math.js
384
lib/math.js
@ -62,14 +62,15 @@ if (typeof(window) != 'undefined') {
|
||||
|
||||
var PRECISION = 1E10;
|
||||
|
||||
var util = {};
|
||||
|
||||
/**
|
||||
* Convert a number to a formatted string representation
|
||||
* @param {Number} value The value to be formatted
|
||||
* @param {Number} [digits] number of digits
|
||||
* @return {String} formattedValue The formatted value
|
||||
* @private
|
||||
*/
|
||||
var format = function (value, digits) {
|
||||
util.format = function (value, digits) {
|
||||
if (value === Infinity) {
|
||||
return 'Infinity';
|
||||
}
|
||||
@ -84,13 +85,13 @@ var format = function (value, digits) {
|
||||
var abs = Math.abs(value);
|
||||
if ( (abs > 0.0001 && abs < 1000000) || abs == 0.0 ) {
|
||||
// round the func to a limited number of digits
|
||||
return String(round(value, digits));
|
||||
return String(util.round(value, digits));
|
||||
}
|
||||
else {
|
||||
// scientific notation
|
||||
var exp = Math.round(Math.log(abs) / Math.LN10);
|
||||
var v = value / (Math.pow(10.0, exp));
|
||||
return round(v, digits) + 'E' + exp;
|
||||
return util.round(v, digits) + 'E' + exp;
|
||||
}
|
||||
};
|
||||
|
||||
@ -100,9 +101,8 @@ var format = function (value, digits) {
|
||||
* @param {Number} value
|
||||
* @param {Number} [digits]
|
||||
* @return {Number} roundedValue
|
||||
* @private
|
||||
*/
|
||||
var round = function (value, digits) {
|
||||
util.round = function (value, digits) {
|
||||
digits = (digits != undefined) ? Math.pow(10, digits) : PRECISION;
|
||||
|
||||
return Math.round(value * digits) / digits;
|
||||
@ -112,9 +112,8 @@ var round = function (value, digits) {
|
||||
* Create a semi UUID
|
||||
* source: http://stackoverflow.com/a/105074/1262753
|
||||
* @return {String} uuid
|
||||
* @private
|
||||
*/
|
||||
var createUUID = function () {
|
||||
util.createUUID = function () {
|
||||
var S4 = function () {
|
||||
return Math.floor(
|
||||
Math.random() * 0x10000 /* 65536 */
|
||||
@ -335,7 +334,7 @@ Unit.prototype.hasBase = function(base) {
|
||||
|
||||
/**
|
||||
* Check if this unit has a base equal to another base
|
||||
* @param {math.type.Unit} other
|
||||
* @param {Unit} other
|
||||
* @return {Boolean} true if equal base
|
||||
*/
|
||||
Unit.prototype.equalBase = function(other) {
|
||||
@ -356,6 +355,7 @@ Unit.prototype.equals = function(other) {
|
||||
* @return {String}
|
||||
*/
|
||||
Unit.prototype.toString = function() {
|
||||
var value;
|
||||
if (!this.fixPrefix) {
|
||||
// find the best prefix value (resulting in the value of which
|
||||
// the absolute value of the log10 is closest to zero,
|
||||
@ -383,12 +383,12 @@ Unit.prototype.toString = function() {
|
||||
}
|
||||
}
|
||||
|
||||
var value = this._unnormalize(this.value, bestPrefix.value);
|
||||
return format(value) + ' ' + bestPrefix.name + this.unit.name;
|
||||
value = this._unnormalize(this.value, bestPrefix.value);
|
||||
return util.format(value) + ' ' + bestPrefix.name + this.unit.name;
|
||||
}
|
||||
else {
|
||||
var value = this._unnormalize(this.value);
|
||||
return format(value) + ' ' + this.prefix.name + this.unit.name;
|
||||
value = this._unnormalize(this.value);
|
||||
return util.format(value) + ' ' + this.prefix.name + this.unit.name;
|
||||
}
|
||||
};
|
||||
|
||||
@ -706,7 +706,7 @@ Complex.prototype.toString = function () {
|
||||
|
||||
if (this.im === 0) {
|
||||
// real value
|
||||
str = format(this.re);
|
||||
str = util.format(this.re);
|
||||
}
|
||||
else if (this.re === 0) {
|
||||
// purely complex value
|
||||
@ -717,25 +717,25 @@ Complex.prototype.toString = function () {
|
||||
str = '-i';
|
||||
}
|
||||
else {
|
||||
str = format(this.im) + 'i';
|
||||
str = util.format(this.im) + 'i';
|
||||
}
|
||||
}
|
||||
else {
|
||||
// complex value
|
||||
if (this.im > 0) {
|
||||
if (this.im == 1) {
|
||||
str = format(this.re) + ' + i';
|
||||
str = util.format(this.re) + ' + i';
|
||||
}
|
||||
else {
|
||||
str = format(this.re) + ' + ' + format(this.im) + 'i';
|
||||
str = util.format(this.re) + ' + ' + util.format(this.im) + 'i';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.im == -1) {
|
||||
str = format(this.re) + ' - i';
|
||||
str = util.format(this.re) + ' - i';
|
||||
}
|
||||
else {
|
||||
str = format(this.re) + ' - ' + format(Math.abs(this.im)) + 'i';
|
||||
str = util.format(this.re) + ' - ' + util.format(Math.abs(this.im)) + 'i';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -853,19 +853,28 @@ math.i = math.I;
|
||||
* Create a TypeError with message:
|
||||
* 'Function <fn> does not support a parameter of type <type>';
|
||||
* @param {String} fn
|
||||
* @param {*} value
|
||||
* @param {*} value1
|
||||
* @param {*} [value2]
|
||||
* @return {TypeError | Error} error
|
||||
*/
|
||||
function newUnsupportedTypeError(fn, value) {
|
||||
var t = type(value);
|
||||
var msg = 'Function ' + fn + ' does not support a parameter of type ' + t;
|
||||
|
||||
if ((typeof TypeError) != 'undefined') {
|
||||
return new TypeError(msg);
|
||||
function newUnsupportedTypeError(fn, value1, value2) {
|
||||
var msg = undefined;
|
||||
if (arguments.length == 2) {
|
||||
var t = type(value1);
|
||||
msg = 'Function ' + fn + ' does not support a parameter of type ' + t;
|
||||
}
|
||||
else if (arguments.length > 2) {
|
||||
var types = [];
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
types += type(arguments[i])
|
||||
}
|
||||
msg = 'Function ' + fn + ' does not support a parameters of type ' + types.join(', ');
|
||||
}
|
||||
else {
|
||||
return new Error(msg);
|
||||
msg = 'Unsupported parameter in function ' + fn;
|
||||
}
|
||||
|
||||
return new TypeError(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -875,7 +884,7 @@ function newUnsupportedTypeError(fn, value) {
|
||||
* @return {Unit} res
|
||||
*/
|
||||
function unit_in(x, unit) {
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
// Test if unit has no value
|
||||
if (unit.hasValue) {
|
||||
throw new Error('Cannot convert to a unit with a value');
|
||||
@ -936,7 +945,7 @@ function sin(x) {
|
||||
);
|
||||
}
|
||||
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
if (!x.hasBase(Unit.BASE_UNITS.ANGLE)) {
|
||||
throw new TypeError ('Unit in function cos is no angle');
|
||||
}
|
||||
@ -975,9 +984,66 @@ sin.doc = {
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes the principal value of the arc tangent of y/x in radians, atan2(y,x)
|
||||
* @param {Number | Complex} y
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function atan2(y, x) {
|
||||
if (isNumber(y)) {
|
||||
if (isNumber(x)) {
|
||||
return Math.atan2(y, x);
|
||||
}
|
||||
else if (x instanceof Complex) {
|
||||
return Math.atan2(y, x.re);
|
||||
}
|
||||
}
|
||||
else if (y instanceof Complex) {
|
||||
if (isNumber(x)) {
|
||||
return Math.atan2(y.re, x);
|
||||
}
|
||||
else if (x instanceof Complex) {
|
||||
return Math.atan2(y.re, x.re);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('atan2', y, x);
|
||||
}
|
||||
|
||||
math.atan2 = atan2;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
atan2.doc = {
|
||||
'name': 'atan2',
|
||||
'category': 'Trigonometry',
|
||||
'syntax': [
|
||||
'atan2(y, x)'
|
||||
],
|
||||
'description':
|
||||
'Computes the principal value of the arc tangent of y/x in radians.',
|
||||
'examples': [
|
||||
'atan2(2, 2) / pi',
|
||||
'angle = 60 deg in rad',
|
||||
'x = cos(angle)',
|
||||
'y = sin(angle)',
|
||||
'atan2(y, x)'
|
||||
],
|
||||
'seealso': [
|
||||
'sin',
|
||||
'cos',
|
||||
'tan'
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the inverse sine of a value, asin(x)
|
||||
* @param {Number | Complex | Unit} x
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function asin(x) {
|
||||
@ -1041,7 +1107,7 @@ asin.doc = {
|
||||
|
||||
/**
|
||||
* Calculate the inverse tangent of a value, atan(x)
|
||||
* @param {Number | Complex | Unit} x
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function atan(x) {
|
||||
@ -1114,7 +1180,7 @@ function cos(x) {
|
||||
);
|
||||
}
|
||||
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
if (!x.hasBase(Unit.BASE_UNITS.ANGLE)) {
|
||||
throw new TypeError ('Unit in function cos is no angle');
|
||||
}
|
||||
@ -1174,7 +1240,7 @@ function tan(x) {
|
||||
);
|
||||
}
|
||||
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
if (!x.hasBase(Unit.BASE_UNITS.ANGLE)) {
|
||||
throw new TypeError ('Unit in function tan is no angle');
|
||||
}
|
||||
@ -1214,7 +1280,7 @@ tan.doc = {
|
||||
|
||||
/**
|
||||
* Calculate the inverse cosine of a value, acos(x)
|
||||
* @param {Number | Complex | Unit} x
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function acos(x) {
|
||||
@ -1276,6 +1342,135 @@ acos.doc = {
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Round a value towards the nearest integer, round(x [, n])
|
||||
* @param {Number | Complex} x
|
||||
* @param {Number} [n] number of digits
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function round(x, n) {
|
||||
if (n == undefined) {
|
||||
// round (x)
|
||||
if (isNumber(x)) {
|
||||
return Math.round(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
Math.round(x.re),
|
||||
Math.round(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
throw newUnsupportedTypeError('round', x);
|
||||
}
|
||||
else {
|
||||
// round (x, n)
|
||||
if (!isNumber(n)) {
|
||||
throw new TypeError('Number of digits in function round must be an integer');
|
||||
}
|
||||
if (n !== Math.round(n)) {
|
||||
throw new TypeError('Number of digits in function round must be integer');
|
||||
}
|
||||
if (n < 0 || n > 9) {
|
||||
throw new Error ('Number of digits in function round must be in te range of 0-9');
|
||||
}
|
||||
|
||||
if (isNumber(x)) {
|
||||
return util.round(x, n);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
util.round(x.re, n),
|
||||
util.round(x.im, n)
|
||||
);
|
||||
}
|
||||
|
||||
throw newUnsupportedTypeError('round', x, n);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
}
|
||||
|
||||
|
||||
math.round = round;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
round.doc = {
|
||||
'name': 'round',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'round(x)',
|
||||
'round(x, n)'
|
||||
],
|
||||
'description':
|
||||
'round a value towards the nearest integer.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards the nearest integer. ' +
|
||||
'When n is specified, the value is rounded to n decimals.',
|
||||
'examples': [
|
||||
'round(3.2)',
|
||||
'round(3.8)',
|
||||
'round(-4.2)',
|
||||
'round(-4.8)',
|
||||
'round(pi, 3)',
|
||||
'round(123.45678, 2)'
|
||||
],
|
||||
'seealso': ['ceil', 'floor', 'fix']
|
||||
};
|
||||
|
||||
/**
|
||||
* Round a value towards zero, fix(x)
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function fix(x) {
|
||||
if (isNumber(x)) {
|
||||
return (value > 0) ? Math.floor(x) : Math.ceil(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
new Complex(
|
||||
(x.re > 0) ? Math.floor(x.re) : Math.ceil(x.re),
|
||||
(x.im > 0) ? Math.floor(x.im) : Math.ceil(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('fix', x);
|
||||
}
|
||||
|
||||
math.fix = fix;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
fix.doc = {
|
||||
'name': 'fix',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'fix(x)'
|
||||
],
|
||||
'description':
|
||||
'Round a value towards zero.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards zero.',
|
||||
'examples': [
|
||||
'fix(3.2)',
|
||||
'fix(3.8)',
|
||||
'fix(-4.2)',
|
||||
'fix(-4.8)'
|
||||
],
|
||||
'seealso': ['ceil', 'floor', 'round']
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the exponent of a value, exp(x)
|
||||
* @param {Number | Complex} x
|
||||
@ -1479,5 +1674,126 @@ log.doc = {
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* Round a value towards minus infinity, floor(x)
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function floor(x) {
|
||||
if (isNumber(x)) {
|
||||
return Math.floor(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
Math.floor(x.re),
|
||||
Math.floor(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('floor', x);
|
||||
}
|
||||
|
||||
math.floor = floor;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
floor.doc = {
|
||||
'name': 'floor',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'floor(x)'
|
||||
],
|
||||
'description':
|
||||
'Round a value towards minus infinity.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards minus infinity.',
|
||||
'examples': [
|
||||
'floor(3.2)',
|
||||
'floor(3.8)',
|
||||
'floor(-4.2)'
|
||||
],
|
||||
'seealso': ['ceil', 'fix', 'round']
|
||||
};
|
||||
|
||||
/**
|
||||
* Round a value towards plus infinity, ceil(x)
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function ceil(x) {
|
||||
if (isNumber(x)) {
|
||||
return Math.ceil(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
Math.ceil(x.re),
|
||||
Math.ceil(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('ceil', x);
|
||||
}
|
||||
|
||||
math.ceil = ceil;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
ceil.doc = {
|
||||
'name': 'ceil',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'ceil(x)'
|
||||
],
|
||||
'description':
|
||||
'Round a value towards plus infinity.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards plus infinity.',
|
||||
'examples': [
|
||||
'ceil(3.2)',
|
||||
'ceil(3.8)',
|
||||
'ceil(-4.2)'
|
||||
],
|
||||
'seealso': ['floor', 'fix', 'round']
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a random number between 0 and 1
|
||||
* @return {Number} res
|
||||
*/
|
||||
function random () {
|
||||
// TODO: implement parameter min and max
|
||||
return Math.random();
|
||||
}
|
||||
|
||||
math.random = random;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
random.doc = {
|
||||
'name': 'random',
|
||||
'category': 'Probability',
|
||||
'syntax': [
|
||||
'random()'
|
||||
],
|
||||
'description':
|
||||
'Return a random number between 0 and 1.',
|
||||
'examples': [
|
||||
'random()',
|
||||
'100 * random()'
|
||||
],
|
||||
'seealso': []
|
||||
};
|
||||
|
||||
|
||||
})();
|
||||
|
||||
2
lib/math.min.js
vendored
2
lib/math.min.js
vendored
File diff suppressed because one or more lines are too long
45
src/function/arithmetic/ceil.js
Normal file
45
src/function/arithmetic/ceil.js
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Round a value towards plus infinity, ceil(x)
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function ceil(x) {
|
||||
if (isNumber(x)) {
|
||||
return Math.ceil(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
Math.ceil(x.re),
|
||||
Math.ceil(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('ceil', x);
|
||||
}
|
||||
|
||||
math.ceil = ceil;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
ceil.doc = {
|
||||
'name': 'ceil',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'ceil(x)'
|
||||
],
|
||||
'description':
|
||||
'Round a value towards plus infinity.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards plus infinity.',
|
||||
'examples': [
|
||||
'ceil(3.2)',
|
||||
'ceil(3.8)',
|
||||
'ceil(-4.2)'
|
||||
],
|
||||
'seealso': ['floor', 'fix', 'round']
|
||||
};
|
||||
46
src/function/arithmetic/fix.js
Normal file
46
src/function/arithmetic/fix.js
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Round a value towards zero, fix(x)
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function fix(x) {
|
||||
if (isNumber(x)) {
|
||||
return (value > 0) ? Math.floor(x) : Math.ceil(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
new Complex(
|
||||
(x.re > 0) ? Math.floor(x.re) : Math.ceil(x.re),
|
||||
(x.im > 0) ? Math.floor(x.im) : Math.ceil(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('fix', x);
|
||||
}
|
||||
|
||||
math.fix = fix;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
fix.doc = {
|
||||
'name': 'fix',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'fix(x)'
|
||||
],
|
||||
'description':
|
||||
'Round a value towards zero.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards zero.',
|
||||
'examples': [
|
||||
'fix(3.2)',
|
||||
'fix(3.8)',
|
||||
'fix(-4.2)',
|
||||
'fix(-4.8)'
|
||||
],
|
||||
'seealso': ['ceil', 'floor', 'round']
|
||||
};
|
||||
45
src/function/arithmetic/floor.js
Normal file
45
src/function/arithmetic/floor.js
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Round a value towards minus infinity, floor(x)
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function floor(x) {
|
||||
if (isNumber(x)) {
|
||||
return Math.floor(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
Math.floor(x.re),
|
||||
Math.floor(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('floor', x);
|
||||
}
|
||||
|
||||
math.floor = floor;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
floor.doc = {
|
||||
'name': 'floor',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'floor(x)'
|
||||
],
|
||||
'description':
|
||||
'Round a value towards minus infinity.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards minus infinity.',
|
||||
'examples': [
|
||||
'floor(3.2)',
|
||||
'floor(3.8)',
|
||||
'floor(-4.2)'
|
||||
],
|
||||
'seealso': ['ceil', 'fix', 'round']
|
||||
};
|
||||
81
src/function/arithmetic/round.js
Normal file
81
src/function/arithmetic/round.js
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Round a value towards the nearest integer, round(x [, n])
|
||||
* @param {Number | Complex} x
|
||||
* @param {Number} [n] number of digits
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function round(x, n) {
|
||||
if (n == undefined) {
|
||||
// round (x)
|
||||
if (isNumber(x)) {
|
||||
return Math.round(x);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
Math.round(x.re),
|
||||
Math.round(x.im)
|
||||
);
|
||||
}
|
||||
|
||||
throw newUnsupportedTypeError('round', x);
|
||||
}
|
||||
else {
|
||||
// round (x, n)
|
||||
if (!isNumber(n)) {
|
||||
throw new TypeError('Number of digits in function round must be an integer');
|
||||
}
|
||||
if (n !== Math.round(n)) {
|
||||
throw new TypeError('Number of digits in function round must be integer');
|
||||
}
|
||||
if (n < 0 || n > 9) {
|
||||
throw new Error ('Number of digits in function round must be in te range of 0-9');
|
||||
}
|
||||
|
||||
if (isNumber(x)) {
|
||||
return util.round(x, n);
|
||||
}
|
||||
|
||||
if (x instanceof Complex) {
|
||||
return new Complex (
|
||||
util.round(x.re, n),
|
||||
util.round(x.im, n)
|
||||
);
|
||||
}
|
||||
|
||||
throw newUnsupportedTypeError('round', x, n);
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
}
|
||||
|
||||
|
||||
math.round = round;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
round.doc = {
|
||||
'name': 'round',
|
||||
'category': 'Arithmetic',
|
||||
'syntax': [
|
||||
'round(x)',
|
||||
'round(x, n)'
|
||||
],
|
||||
'description':
|
||||
'round a value towards the nearest integer.' +
|
||||
'If x is complex, both real and imaginary part are rounded ' +
|
||||
'towards the nearest integer. ' +
|
||||
'When n is specified, the value is rounded to n decimals.',
|
||||
'examples': [
|
||||
'round(3.2)',
|
||||
'round(3.8)',
|
||||
'round(-4.2)',
|
||||
'round(-4.8)',
|
||||
'round(pi, 3)',
|
||||
'round(123.45678, 2)'
|
||||
],
|
||||
'seealso': ['ceil', 'floor', 'fix']
|
||||
};
|
||||
28
src/function/probability/random.js
Normal file
28
src/function/probability/random.js
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Return a random number between 0 and 1
|
||||
* @return {Number} res
|
||||
*/
|
||||
function random () {
|
||||
// TODO: implement parameter min and max
|
||||
return Math.random();
|
||||
}
|
||||
|
||||
math.random = random;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
random.doc = {
|
||||
'name': 'random',
|
||||
'category': 'Probability',
|
||||
'syntax': [
|
||||
'random()'
|
||||
],
|
||||
'description':
|
||||
'Return a random number between 0 and 1.',
|
||||
'examples': [
|
||||
'random()',
|
||||
'100 * random()'
|
||||
],
|
||||
'seealso': []
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Calculate the inverse cosine of a value, acos(x)
|
||||
* @param {Number | Complex | Unit} x
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function acos(x) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Calculate the inverse sine of a value, asin(x)
|
||||
* @param {Number | Complex | Unit} x
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function asin(x) {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Calculate the inverse tangent of a value, atan(x)
|
||||
* @param {Number | Complex | Unit} x
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function atan(x) {
|
||||
|
||||
56
src/function/trigonometry/atan2.js
Normal file
56
src/function/trigonometry/atan2.js
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Computes the principal value of the arc tangent of y/x in radians, atan2(y,x)
|
||||
* @param {Number | Complex} y
|
||||
* @param {Number | Complex} x
|
||||
* @return {Number | Complex} res
|
||||
*/
|
||||
function atan2(y, x) {
|
||||
if (isNumber(y)) {
|
||||
if (isNumber(x)) {
|
||||
return Math.atan2(y, x);
|
||||
}
|
||||
else if (x instanceof Complex) {
|
||||
return Math.atan2(y, x.re);
|
||||
}
|
||||
}
|
||||
else if (y instanceof Complex) {
|
||||
if (isNumber(x)) {
|
||||
return Math.atan2(y.re, x);
|
||||
}
|
||||
else if (x instanceof Complex) {
|
||||
return Math.atan2(y.re, x.re);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement array support
|
||||
// TODO: implement matrix support
|
||||
|
||||
throw newUnsupportedTypeError('atan2', y, x);
|
||||
}
|
||||
|
||||
math.atan2 = atan2;
|
||||
|
||||
/**
|
||||
* Function documentation
|
||||
*/
|
||||
atan2.doc = {
|
||||
'name': 'atan2',
|
||||
'category': 'Trigonometry',
|
||||
'syntax': [
|
||||
'atan2(y, x)'
|
||||
],
|
||||
'description':
|
||||
'Computes the principal value of the arc tangent of y/x in radians.',
|
||||
'examples': [
|
||||
'atan2(2, 2) / pi',
|
||||
'angle = 60 deg in rad',
|
||||
'x = cos(angle)',
|
||||
'y = sin(angle)',
|
||||
'atan2(y, x)'
|
||||
],
|
||||
'seealso': [
|
||||
'sin',
|
||||
'cos',
|
||||
'tan'
|
||||
]
|
||||
};
|
||||
@ -16,7 +16,7 @@ function cos(x) {
|
||||
);
|
||||
}
|
||||
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
if (!x.hasBase(Unit.BASE_UNITS.ANGLE)) {
|
||||
throw new TypeError ('Unit in function cos is no angle');
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ function sin(x) {
|
||||
);
|
||||
}
|
||||
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
if (!x.hasBase(Unit.BASE_UNITS.ANGLE)) {
|
||||
throw new TypeError ('Unit in function cos is no angle');
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ function tan(x) {
|
||||
);
|
||||
}
|
||||
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
if (!x.hasBase(Unit.BASE_UNITS.ANGLE)) {
|
||||
throw new TypeError ('Unit in function tan is no angle');
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* @return {Unit} res
|
||||
*/
|
||||
function unit_in(x, unit) {
|
||||
if (isUnit(x)) {
|
||||
if (x instanceof Unit) {
|
||||
// Test if unit has no value
|
||||
if (unit.hasValue) {
|
||||
throw new Error('Cannot convert to a unit with a value');
|
||||
|
||||
@ -6,17 +6,26 @@
|
||||
* Create a TypeError with message:
|
||||
* 'Function <fn> does not support a parameter of type <type>';
|
||||
* @param {String} fn
|
||||
* @param {*} value
|
||||
* @param {*} value1
|
||||
* @param {*} [value2]
|
||||
* @return {TypeError | Error} error
|
||||
*/
|
||||
function newUnsupportedTypeError(fn, value) {
|
||||
var t = type(value);
|
||||
var msg = 'Function ' + fn + ' does not support a parameter of type ' + t;
|
||||
|
||||
if ((typeof TypeError) != 'undefined') {
|
||||
return new TypeError(msg);
|
||||
function newUnsupportedTypeError(fn, value1, value2) {
|
||||
var msg = undefined;
|
||||
if (arguments.length == 2) {
|
||||
var t = type(value1);
|
||||
msg = 'Function ' + fn + ' does not support a parameter of type ' + t;
|
||||
}
|
||||
else if (arguments.length > 2) {
|
||||
var types = [];
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
types += type(arguments[i])
|
||||
}
|
||||
msg = 'Function ' + fn + ' does not support a parameters of type ' + types.join(', ');
|
||||
}
|
||||
else {
|
||||
return new Error(msg);
|
||||
msg = 'Unsupported parameter in function ' + fn;
|
||||
}
|
||||
|
||||
return new TypeError(msg);
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ Complex.prototype.toString = function () {
|
||||
|
||||
if (this.im === 0) {
|
||||
// real value
|
||||
str = format(this.re);
|
||||
str = util.format(this.re);
|
||||
}
|
||||
else if (this.re === 0) {
|
||||
// purely complex value
|
||||
@ -50,25 +50,25 @@ Complex.prototype.toString = function () {
|
||||
str = '-i';
|
||||
}
|
||||
else {
|
||||
str = format(this.im) + 'i';
|
||||
str = util.format(this.im) + 'i';
|
||||
}
|
||||
}
|
||||
else {
|
||||
// complex value
|
||||
if (this.im > 0) {
|
||||
if (this.im == 1) {
|
||||
str = format(this.re) + ' + i';
|
||||
str = util.format(this.re) + ' + i';
|
||||
}
|
||||
else {
|
||||
str = format(this.re) + ' + ' + format(this.im) + 'i';
|
||||
str = util.format(this.re) + ' + ' + util.format(this.im) + 'i';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.im == -1) {
|
||||
str = format(this.re) + ' - i';
|
||||
str = util.format(this.re) + ' - i';
|
||||
}
|
||||
else {
|
||||
str = format(this.re) + ' - ' + format(Math.abs(this.im)) + 'i';
|
||||
str = util.format(this.re) + ' - ' + util.format(Math.abs(this.im)) + 'i';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ Unit.prototype.hasBase = function(base) {
|
||||
|
||||
/**
|
||||
* Check if this unit has a base equal to another base
|
||||
* @param {math.type.Unit} other
|
||||
* @param {Unit} other
|
||||
* @return {Boolean} true if equal base
|
||||
*/
|
||||
Unit.prototype.equalBase = function(other) {
|
||||
@ -193,6 +193,7 @@ Unit.prototype.equals = function(other) {
|
||||
* @return {String}
|
||||
*/
|
||||
Unit.prototype.toString = function() {
|
||||
var value;
|
||||
if (!this.fixPrefix) {
|
||||
// find the best prefix value (resulting in the value of which
|
||||
// the absolute value of the log10 is closest to zero,
|
||||
@ -220,12 +221,12 @@ Unit.prototype.toString = function() {
|
||||
}
|
||||
}
|
||||
|
||||
var value = this._unnormalize(this.value, bestPrefix.value);
|
||||
return format(value) + ' ' + bestPrefix.name + this.unit.name;
|
||||
value = this._unnormalize(this.value, bestPrefix.value);
|
||||
return util.format(value) + ' ' + bestPrefix.name + this.unit.name;
|
||||
}
|
||||
else {
|
||||
var value = this._unnormalize(this.value);
|
||||
return format(value) + ' ' + this.prefix.name + this.unit.name;
|
||||
value = this._unnormalize(this.value);
|
||||
return util.format(value) + ' ' + this.prefix.name + this.unit.name;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
15
src/util.js
15
src/util.js
@ -1,14 +1,15 @@
|
||||
|
||||
var PRECISION = 1E10;
|
||||
|
||||
var util = {};
|
||||
|
||||
/**
|
||||
* Convert a number to a formatted string representation
|
||||
* @param {Number} value The value to be formatted
|
||||
* @param {Number} [digits] number of digits
|
||||
* @return {String} formattedValue The formatted value
|
||||
* @private
|
||||
*/
|
||||
var format = function (value, digits) {
|
||||
util.format = function (value, digits) {
|
||||
if (value === Infinity) {
|
||||
return 'Infinity';
|
||||
}
|
||||
@ -23,13 +24,13 @@ var format = function (value, digits) {
|
||||
var abs = Math.abs(value);
|
||||
if ( (abs > 0.0001 && abs < 1000000) || abs == 0.0 ) {
|
||||
// round the func to a limited number of digits
|
||||
return String(round(value, digits));
|
||||
return String(util.round(value, digits));
|
||||
}
|
||||
else {
|
||||
// scientific notation
|
||||
var exp = Math.round(Math.log(abs) / Math.LN10);
|
||||
var v = value / (Math.pow(10.0, exp));
|
||||
return round(v, digits) + 'E' + exp;
|
||||
return util.round(v, digits) + 'E' + exp;
|
||||
}
|
||||
};
|
||||
|
||||
@ -39,9 +40,8 @@ var format = function (value, digits) {
|
||||
* @param {Number} value
|
||||
* @param {Number} [digits]
|
||||
* @return {Number} roundedValue
|
||||
* @private
|
||||
*/
|
||||
var round = function (value, digits) {
|
||||
util.round = function (value, digits) {
|
||||
digits = (digits != undefined) ? Math.pow(10, digits) : PRECISION;
|
||||
|
||||
return Math.round(value * digits) / digits;
|
||||
@ -51,9 +51,8 @@ var round = function (value, digits) {
|
||||
* Create a semi UUID
|
||||
* source: http://stackoverflow.com/a/105074/1262753
|
||||
* @return {String} uuid
|
||||
* @private
|
||||
*/
|
||||
var createUUID = function () {
|
||||
util.createUUID = function () {
|
||||
var S4 = function () {
|
||||
return Math.floor(
|
||||
Math.random() * 0x10000 /* 65536 */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user