INTRODUCTION
A simple to use and efficient evaluator for math expressions in Javascript.
Topics
- Installation
- Supported Math Symbols
- Usage
Installation
Node js
var mexp = require('math-expression-evaluator');
Browser
<script src="math-expression-evaluator.js"></script>
This will export a global variable named mexp which can be used as given below.
Supported Maths Symbols
+ Addition Operator eg. 2+3 results 5
- Subtraction Operator eg. 2-3 results -1
/ Division operator eg 3/2 results 1.5
\ Multiplication Operator eg. 23 results 6
Mod Modulus Operator eg. 3 Mod 2 results 1
( Opening Parenthesis
) Closing Parenthesis
Sigma Summation eg. Sigma(1,100,n) results 5050
Pi Product eg. Pi(1,10,n) results 3628800
n Variable for Summation or Product
pi Math constant pi returns 3.14
e Math constant e returns 2.71
C Combination operator eg. 4C2 returns 6
P Permutation operator eg. 4P2 returns 12
! factorial operator eg. 4! returns 24
log logarithmic function with base 10 eg. log 1000 returns 3
ln natural log function with base e eg. ln 2 returns .3010
pow power function with two operator pow(2,3) returns 8
^ power operator eg. 2^3 returns 8
root underroot function root 4 returns 2
Trigonometric function
sin
cos
tan
asin
acos
atan
sinh
cosh
tanh
asinh
acosh
atanh
Usage
An expression can be evaluated using
Using eval method of mexp object
var value = mexp.eval(exp);
Using constituents of eval methods of mexp object
-
Parse an expression and then add additional detail to the tokens using
var lexed = mexp.lex(exp);
which returns a
mexp
constructor object which will be further processed by methodstoPostfix
andpostfixEval
-
Now, that object is needed to be converted to postfix notation using
var postfix = lexed.toPostfix();
which converts the
mexp
object to postfix notation and return newmexp
object -
Now to get the value of expression use
postfixEval
var result = postfix.postfixEval();
where result contains the result.
Extending tokens
How to define a token
To create a token that represent any function, variable,operator etc. a object needs to be declared with four properties.
1. token( string that is unique and used for tokenization)
This property is used to identify and tokenize the string .This needs to be unique for every token.
2. type
These are the following type that should be chose suitably when creating a tokens
0 : function with syntax function_name(Maths_exp)
2 : binary function with syntax (Math_exp1)function_name(Math_exp2) eg. * / Mod
3 : Math constant values like e,pi
7 : function with syntax (Math_exp)function_name eg. !
8 : function with two comma separated parameters syntax function_name(Math_exp1,Math_exp2) eg. pow
12: function of Sigma or Pi kind which have three comma separated parameters function_name(Math_exp1,Math_exp2,Math_exp3) eg. pow
3. value
What is the value stored in that token.
In detail for any function `value` should be a Javascript function with the corresponding arguments.
4. show( string to show when displaying parsed formula)
This is the value to display when the executed formula is displayed using `Mexp.formulaEval()`.
For eg. sin has `show` property sin while Sigma has show property `Σ` so that it displays Σ instead if plain Sigma.
Function with one parameter
For defining a token for function which accepts only one argument like sine, an object with all four properties as explained above needs to be defined. For function with only one argument
type
must be 0
token
will be the function name
show
can also be the function name as it is only used for displaying formula
value
needs to be a function that accepts and operates on one argument.
Eg. Object if a function needs to be added for inverse of a number
{
type:0,
token:"inverse",
show:"inverse",
value:function(a){
return 1/a;
}
}
Function with two parameters
For defining a token for function which accepts two arguments like pow, an object with all four properties as explained above needs to be defined. For function with two argument
type
must be 8
token
will be the function name
show
can also be the function name as it is only used for displaying formula
value
needs to be a function that accepts and operates on two arguments.
Eg. Object if a function needs to be added for finding maximum of two number
{
type:8,
token:"max",
show:"max",
value:function(a,b){
if(a>b)
return a;
return b;
}
}
Sigma or Pi kind functions with three parameters
For defining a token for function which accepts three arguments like Sigma, an object with all four properties as explained above needs to be defined. For function with three argument
type
must be 12
token
will be the function name
show
can also be the function name as it is only used for displaying formula
value
needs to be a function that accepts and operates on two arguments.
Eg. Object if a function needs to be added for finding maximum of n expression from i to k number
{
type:12,
token:"max_three",
show:"max_three",
value:function(a,b,c){
var max=c.postfixEval({n:a}),temp;
for(var i=a+1;i<b;i++){
var temp=c.postfixEval({n:i});
if(temp>max)
max=temp;
}
return max;
}
}
Variable
For defining a token for variable like pi, an object with all four properties as explained above needs to be defined. For a variable
type
must be 3
token
will be the token name
show
can be anything for displaying formula
value
needs to be the unique name can also be token name.
Note : Value of the variable needs to be passed separately to the evaluator either in eval
method or it's constituent postfixEval
method
Eg. Object to add a variable named git
{
type:3,
token:"git",
show:"git",
value:"git"
}
Unary postfix function
For defining a token for postfix function which accepts one arguments like factorial !, an object with all four properties as explained above needs to be defined. For postfix function with one argument
type
must be 7
token
will be the function name
show
can also be the function name as it is only used for displaying formula
value
needs to be a function that accepts and operates on one arguments.
Eg. Object if a postfix function needs to be added for inverse of a number
{
type:7,
token:"inverse",
show:"inverse",
value:function(a){
return 1/a;
}
}
Binary infix function
For defining a token for infix function which accepts two arguments like *,/ or Mod, an object with all four properties as explained above needs to be defined. For infix function with two argument
type
must be 2
token
will be the function name
show
can also be the function name as it is only used for displaying formula
value
needs to be a function that accepts and operates on two arguments.
Eg. Object if a binary function needs to be added for finding maximum of two number
{
type:2,
token:"max",
show:"max",
value:function(a,b){
if(a>b)
return a;
return b;
}
}
Adding tokens using addToken method of mexp object
Mexp.addToken([token1,token2,...]);
This method taken a list of tokens which are explained above as arguments and adds them to the built-in tokens. After that the evaluator can be used as usual.
Note : If a variable is being added to the evaluator then the value of the variable needs to be passed as explained below.
Adding tokens using eval method of mexp object
var value = =mexp.eval(exp,[token1,token2,...],pair);
eval
method takes three arguments where
- first is the expression to be evaluated
- second is list of tokens where structure of token is explained here
- third is the key-value pair object. This object is the key-value mappings for all the variables added to the evaluator where key is equal to value property of token and value is equal to some number.
Eg. For this token, the pair object would look like
{"git":100}
Adding token using constituents of eval method of mexp object
var lexed = mexp.lex(exp,[token1,token2,...]);
lex
method takes list of tokens as explained here as second second arguments.
If variables are added to the evaluator then key-value pair needs to be passed to postfixEval
method
var result = postfix.postfixEval(pair);
where pair object is the key-value mappings for all the variable where key is equal to value property of token and value is equal to some number.
Eg. For this token, the pair object would look like
{"git":100}
Error handling
This evaluator throws exception with error message if any error occurs.
So it is a good habit to catch the exception
try{
mexp.eval("sin()");
}
catch(e){
alert(e.message); //alert ) is not allowed after (
}