math-expression-evaluator
Advanced tools
Comparing version 1.2.1 to 1.2.2
{ | ||
"name": "math-expression-evaluator", | ||
"version": "1.2.1", | ||
"version": "1.2.2", | ||
"description": "A flexible math expression evaluator", | ||
@@ -5,0 +5,0 @@ "main": "src/formula_evaluator.js", |
132
README.md
@@ -0,7 +1,22 @@ | ||
# Introduction | ||
An extremely efficient, flexible and amazing evaluator with a smart parser for Math expression using Javascript.It has all the basic functions supported with extensive support for new functions, variable etc. | ||
Plus it supports Sigma and Pi notations too. Also, any human readable math expression like `sincostan90` is also readable by this evaluator. | ||
An extremelyt efficient evaluator with a smart parser for Math expression using Javascript. This evaluator will add some parenthesis if the user misses some. In short, any human readable math expression like `sincostan90` or `Sigma1,Sigma1,2,n,n`( which will give 6 as `Sigma(1 , Sigma(1 , 2 , n) , n) )` ) is also readable by this evaluator | ||
##[Demonstration](http://jsbin.com/qokime/edit?html,output) | ||
#Topics | ||
- [Features](#features) | ||
- [Supported symbols](#supported-symbols) | ||
- [Amazing support for Sigma and Pi](#amazing-support-for-sigma-and-pi) | ||
- [Parenthesis less expressions](#parenthesis-less-expression) | ||
- [Installation](#installation) | ||
- [Node JS](#node-js) | ||
- [Browser](#browser) | ||
- [Test](#test) | ||
- [Documentation](http://ankit31894.github.io/math-expression-evaluator/) | ||
# Installation | ||
@@ -17,74 +32,49 @@ ## Node JS | ||
bower install math-expression-evaluator | ||
# Supported Maths Symbols | ||
# Features | ||
##Supported symbols | ||
**+** Addition Operator eg. 2+3 results 5 | ||
**+** 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. 2\*3 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** | ||
**-** Subtraction Operator eg. 2-3 results -1 | ||
##Amazing support for Sigma and Pi | ||
This is a fantastic feature of this calculator that it is capable of evaluating expressions containing **Sigma and Pi**. | ||
Passing `Sigma(1,100,n)` will evaluate to 5050 as n is summationed from 1 to 100. | ||
and Pi(1,15,n) will evaluate to 1307674368000 as n is multiplied from 1 to 15 which is equal to 15! | ||
**/** Division operator eg 3/2 results 1.5 | ||
##Parenthesis less expression | ||
If a expression is readable by human then it is readable by this evaluator. There is no need to wrap every function inside parenthesis. | ||
For eg. sin90 will work totally fine instead of sin(90) | ||
**\*** Multiplication Operator eg. 2*3 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** | ||
# Test | ||
npm test | ||
##[Documentation](http://ankit31894.github.io/math-expression-evaluator/) | ||
# Test | ||
npm test |
@@ -12,7 +12,7 @@ var Mexp=require('./postfix_evaluator.js'); | ||
} | ||
else if(arr[i].type===23){ | ||
else if(arr[i].type===13){ | ||
disp.push({value:arr[i].show,type:1}); | ||
} | ||
else if(arr[i].type===0){ | ||
disp[disp.length-1]={value:arr[i].show+disp[disp.length-1].value+(arr[i].show!="-"?")":""),type:0}; | ||
disp[disp.length-1]={value:arr[i].show+(arr[i].show!="-"?"(":"")+disp[disp.length-1].value+(arr[i].show!="-"?")":""),type:0}; | ||
} | ||
@@ -22,6 +22,6 @@ else if(arr[i].type===7){ | ||
} | ||
else if(arr[i].type===11){ | ||
else if(arr[i].type===10){ | ||
pop1=disp.pop(); | ||
pop2=disp.pop(); | ||
if(arr[i].show==='P'||arr[i].show==='C')disp.push({value:"<sup>"+pop2+"</sup>"+arr[i].show+"<sub>"+pop1+"</sub>",type:11}); | ||
if(arr[i].show==='P'||arr[i].show==='C')disp.push({value:"<sup>"+pop2+"</sup>"+arr[i].show+"<sub>"+pop1+"</sub>",type:10}); | ||
else disp.push({value:(pop2.type!=1?"(":"")+pop2.value+(pop2.type!=1?")":"")+"<sup>"+pop1.value+"</sup>",type:1}); | ||
@@ -34,7 +34,7 @@ } | ||
} | ||
else if(arr[i].type===22){ | ||
else if(arr[i].type===12){ | ||
pop1=disp.pop(); | ||
pop2=disp.pop(); | ||
pop3=disp.pop(); | ||
disp.push({value:arr[i].show+"("+pop3.value+","+pop2.value+","+pop1.value+")",type:22}); | ||
disp.push({value:arr[i].show+"("+pop3.value+","+pop2.value+","+pop1.value+")",type:12}); | ||
} | ||
@@ -41,0 +41,0 @@ } |
@@ -9,29 +9,25 @@ | ||
} | ||
var token=['sin','cos','tan','pi','(',')','Del','P','C', | ||
var token=['sin','cos','tan','pi','(',')','P','C', | ||
'asin','acos','atan','7','8','9','int', | ||
'cosh','acosh','ln','^','root','4','5','6','/','!', | ||
'tanh','atanh','Mod','1','2','3','*','=', | ||
'sinh','asinh','e','log','10^x','0','.','+','-',',','Sigma','n','Pi','pow']; | ||
var show=['sin(','cos(','tan(','π','(',')','Del','P','C', | ||
'asin(','acos(','atan(','7','8','9','Int(', | ||
'cosh(','acosh(',' ln(','^','root(','4','5','6','÷','!', | ||
'tanh(','atanh(',' Mod ','1','2','3','×','=', | ||
'sinh(','asinh(','e',' log(',' 10^(','0','.','+','-',',','Σ','n','Π','pow(']; | ||
var eva=[Mexp.math.sin,Mexp.math.cos,Mexp.math.tan,'PI','(',')','Del',Mexp.math.P,Mexp.math.C, | ||
'tanh','atanh','Mod','1','2','3','*', | ||
'sinh','asinh','e','log','0','.','+','-',',','Sigma','n','Pi','pow']; | ||
var show=['sin','cos','tan','π','(',')','P','C', | ||
'asin','acos','atan','7','8','9','Int', | ||
'cosh','acosh',' ln','^','root','4','5','6','÷','!', | ||
'tanh','atanh',' Mod ','1','2','3','×', | ||
'sinh','asinh','e',' log','0','.','+','-',',','Σ','n','Π','pow']; | ||
var eva=[Mexp.math.sin,Mexp.math.cos,Mexp.math.tan,'PI','(',')',Mexp.math.P,Mexp.math.C, | ||
Mexp.math.asin,Mexp.math.acos,Mexp.math.atan,'7','8','9',Math.floor, | ||
Mexp.math.cosh,Mexp.math.acosh,Math.log,Math.pow,Math.pow,'4','5','6',Mexp.math.div,Mexp.math.fact, | ||
Mexp.math.tanh,Mexp.math.atanh,Mexp.math.mod,'1','2','3',Mexp.math.mul,'=', | ||
Mexp.math.sinh,Mexp.math.asinh,'E',Mexp.math.log,Mexp.math.pow10x,'0','.',Mexp.math.add,Mexp.math.sub,',',Mexp.math.sigma,'n',Mexp.math.Pi,Math.pow]; | ||
var preced=[11,11,11,0,0,0,0,7,7, | ||
11,11,10,0,0,0,11, | ||
11,11,10,10,11,0,0,0,3,11, | ||
11,11,10,0,0,0,3,0, | ||
11,11,0,11,11,0,0,1,1,0,11,0,11,11]; | ||
var type=[0,0,0,3,4,5,12,11,11, | ||
Mexp.math.tanh,Mexp.math.atanh,Mexp.math.mod,'1','2','3',Mexp.math.mul, | ||
Mexp.math.sinh,Mexp.math.asinh,'E',Mexp.math.log,'0','.',Mexp.math.add,Mexp.math.sub,',',Mexp.math.sigma,'n',Mexp.math.Pi,Math.pow]; | ||
var preced={0:11,1:0,2:3,3:0,4:0,5:0,6:0,7:11,8:11,9:1,10:10,11:0,12:11,13:0}; | ||
var type=[0,0,0,3,4,5,10,10, | ||
0,0,0,1,1,1,0, | ||
0,0,0,11,11,1,1,1,2,7, | ||
0,0,2,1,1,1,2,13, | ||
0,0,3,0,0,1,6,9,9,21,22,23,22,8]; | ||
0,0,0,10,0,1,1,1,2,7, | ||
0,0,2,1,1,1,2, | ||
0,0,3,0,1,6,9,9,11,12,13,12,8]; | ||
/* | ||
0 : function with syntax function_name(Maths_exp) whose math_exp is yet to be entered | ||
0 : function with syntax function_name(Maths_exp) | ||
1 : numbers | ||
@@ -46,13 +42,12 @@ 2 : binary operators like * / % | ||
9 : binary operator like +,- | ||
11: function with syntax (Math_exp1)function_name(Math_exp2) whose exp2 is yet to be entered | ||
12: Delete Button | ||
13: = button | ||
22: function with , seperated three parameters | ||
23: variable of Sigma function | ||
10: function with syntax (Math_exp1)function_name(Math_exp2) | ||
11: , | ||
12: function with , seperated three parameters | ||
13: variable of Sigma function | ||
*/ | ||
var type0={0:true,1:true,3:true,4:true,6:true,8:true,9:true,17:true,22:true,23:true}, //type2:true,type4:true,type9:true,type11:true,type21:true,type22 | ||
type1={0:true,1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true,9:true,10:true,11:true,13:true,17:true,21:true,22:true,23:true},//type3:true,type5:true,type7:true,type23 | ||
type_1={0:true,3:true,4:true,8:true,17:true,22:true,23:true}, | ||
var type0={0:true,1:true,3:true,4:true,6:true,8:true,9:true,12:true,13:true},//type2:true,type4:true,type9:true,type11:true,type21:true,type22 | ||
type1={0:true,1:true,2:true,3:true,4:true,5:true,6:true,7:true,8:true,9:true,10:true,11:true,12:true,13:true},//type3:true,type5:true,type7:true,type23 | ||
type_1={0:true,3:true,4:true,8:true,12:true,13:true}, | ||
empty={}, | ||
type_3={0:true,1:true,3:true,4:true,6:true,8:true,17:true,22:true,23:true},//type_5:true,type_7:true,type_23 | ||
type_3={0:true,1:true,3:true,4:true,6:true,8:true,12:true,13:true},//type_5:true,type_7:true,type_23 | ||
type6={1:true}, | ||
@@ -90,3 +85,2 @@ newAr=[[], | ||
eva.push(tokens[i].ev); | ||
preced.push(tokens[i].preced); | ||
show.push(tokens[i].show); | ||
@@ -98,3 +92,2 @@ } | ||
eva[temp]=tokens[i].ev; | ||
preced[temp]=tokens[i].preced; | ||
show[temp]=tokens[i].show; | ||
@@ -137,3 +130,3 @@ } | ||
var cEv=eva[index]; | ||
var cPre=preced[index]; | ||
var cPre=preced[cType]; | ||
var cShow=show[index]; | ||
@@ -143,7 +136,7 @@ var pre=str[str.length-1]; | ||
if(ptc[j]===0){ | ||
if([0,2,3,5,9,21,22,23].indexOf(cType)!==-1){ | ||
if([0,2,3,5,9,11,12,13].indexOf(cType)!==-1){ | ||
if(allowed[cType]!==true){ | ||
throw(new Mexp.exception(key+" is not allowed after "+prevKey)); | ||
} | ||
str.push({value:")",type:5,pre:3,show:")"}); | ||
str.push({value:")",type:5,pre:0,show:")"}); | ||
allowed=type1; | ||
@@ -240,3 +233,3 @@ asterick=type_3; | ||
if(pre.type===9){ | ||
if(pre.value==='+'){ | ||
if(pre.value===Mexp.math.add){ | ||
pre.value=cEv; | ||
@@ -246,4 +239,4 @@ pre.show=cShow; | ||
} | ||
else if(pre.value==='-'&&cShow==='-'){ | ||
pre.value='+'; | ||
else if(pre.value===Mexp.math.sub&&cShow==='-'){ | ||
pre.value=Mexp.math.add; | ||
pre.show='+'; | ||
@@ -253,5 +246,8 @@ inc(ptc,1); | ||
} | ||
else if(pre.type!==5&&pre.type!==7&&pre.type!==1&&pre.type!==3&&pre.type!==23){ | ||
else if(pre.type!==5&&pre.type!==7&&pre.type!==1&&pre.type!==3&&pre.type!==13){ | ||
allowed=type0; | ||
asterick=empty; | ||
inc(ptc,2).push(2); | ||
str.push({value:Mexp.math.changeSign,type:0,pre:21,show:"-"}); | ||
inc(ptc,1); | ||
str.push({value:"(",type:4,pre:0,show:"("}); | ||
} | ||
@@ -265,3 +261,3 @@ else{ | ||
} | ||
else if(cType===11){ | ||
else if(cType===10){ | ||
allowed=type0; | ||
@@ -272,3 +268,3 @@ asterick=empty; | ||
} | ||
else if(cType===21){ | ||
else if(cType===11){ | ||
allowed=type0; | ||
@@ -278,3 +274,3 @@ asterick=empty; | ||
} | ||
else if(cType===22){ | ||
else if(cType===12){ | ||
allowed=type0; | ||
@@ -286,3 +282,3 @@ asterick=empty; | ||
} | ||
else if(cType===23){ | ||
else if(cType===13){ | ||
allowed=type1; | ||
@@ -289,0 +285,0 @@ asterick=type_3; |
@@ -1,5 +0,2 @@ | ||
var Mexp=function(parsed,error){ | ||
if (error) { | ||
this.value=[]; | ||
} | ||
var Mexp=function(parsed){ | ||
this.value=parsed; | ||
@@ -94,2 +91,6 @@ | ||
var sum=0; | ||
if (ex.constructor!==Array) { //pop1 needs to be constructor | ||
ex=[{type:1,value:ex}]; | ||
} | ||
ex=new Mexp(ex); | ||
for(var i=low;i<=high;i++){ | ||
@@ -96,0 +97,0 @@ sum+=Number(ex.postfixEval({n:i})); |
@@ -21,3 +21,3 @@ var Mexp=require('./postfix.js'); | ||
if(typeof stack[stack.length-1].type==="undefined"){ | ||
stack[stack.length-1].push(arr[i]); | ||
stack[stack.length-1].value.push(arr[i]); | ||
} | ||
@@ -28,3 +28,3 @@ else stack[stack.length-1].value=arr[i].value(stack[stack.length-1].value); | ||
if(typeof stack[stack.length-1].type==="undefined"){ | ||
stack[stack.length-1].push(arr[i]); | ||
stack[stack.length-1].value.push(arr[i]); | ||
} | ||
@@ -38,13 +38,13 @@ else stack[stack.length-1].value=arr[i].value(stack[stack.length-1].value); | ||
} | ||
else if(arr[i].type===11){ | ||
else if(arr[i].type===10){ | ||
pop1=stack.pop(); | ||
pop2=stack.pop(); | ||
if(typeof pop2.type==="undefined"){ | ||
pop2=pop2.concat(pop1); | ||
pop2.push(arr[i]); | ||
pop2.value=pop2.value.concat(pop1); | ||
pop2.value.push(arr[i]); | ||
stack.push(pop2); | ||
} | ||
else if (typeof pop1.type==="undefined") { | ||
pop1.unshift(pop2); | ||
pop1.push(arr[i]); | ||
pop1.value.unshift(pop2); | ||
pop1.value.push(arr[i]); | ||
stack.push(pop1); | ||
@@ -59,9 +59,9 @@ } | ||
if(typeof pop2.type==="undefined"){ | ||
pop2=pop2.concat(pop1); | ||
pop2.push(arr[i]); | ||
pop2=pop2.value.concat(pop1); | ||
pop2.value.push(arr[i]); | ||
stack.push(pop2); | ||
} | ||
else if (typeof pop1.type==="undefined") { | ||
pop1.unshift(pop2); | ||
pop1.push(arr[i]); | ||
pop1.value.unshift(pop2); | ||
pop1.value.push(arr[i]); | ||
stack.push(pop1); | ||
@@ -73,20 +73,17 @@ } | ||
} | ||
else if(arr[i].type===22){ | ||
else if(arr[i].type===12){ | ||
pop1=stack.pop(); | ||
pop2=stack.pop(); | ||
pop3=stack.pop(); | ||
if (pop1.constructor!==Array) { //pop1 needs to be constructor | ||
pop1=[pop1]; | ||
} | ||
stack.push({type:1,value:arr[i].value(pop3.value,pop2.value,new Mexp(pop1))}); | ||
stack.push({type:1,value:arr[i].value(pop3.value,pop2.value,pop1.value)}); | ||
} | ||
else if(arr[i].type===23){ | ||
else if(arr[i].type===13){ | ||
if(bool){ | ||
stack.push({value:UserDefined[arr[i].value],type:3}); | ||
} | ||
else stack.push([arr[i]]); | ||
else stack.push({value:[arr[i]]}); | ||
} | ||
} | ||
if (stack.length>1) { | ||
throw(new Mexp.exception("Math error")); | ||
throw(new Mexp.exception("Uncaught Syntax error")); | ||
} | ||
@@ -93,0 +90,0 @@ return stack[0].value>1000000000000000?"Infinity":Number(stack[0].value.toFixed(15)).toPrecision(); |
@@ -18,3 +18,3 @@ | ||
for (var i=1; i < arr.length; i++) { | ||
if(arr[i].type===1||arr[i].type===3||arr[i].type===23){ //if token is number,constant,or n(which is also a special constant in our case) | ||
if(arr[i].type===1||arr[i].type===3||arr[i].type===13){ //if token is number,constant,or n(which is also a special constant in our case) | ||
if(arr[i].type===1) | ||
@@ -32,3 +32,3 @@ arr[i].value=Number(arr[i].value); | ||
} | ||
else if(arr[i].type===21){ | ||
else if(arr[i].type===11){ | ||
while((popped=stack.pop()).type!==4){ | ||
@@ -35,0 +35,0 @@ post.push(popped); |
@@ -18,5 +18,21 @@ // This test is for node JS | ||
}); | ||
it('minus with exponent test', function () { | ||
assert.equal(a.lex("0+-2^2").toPostfix().postfixEval(),-4); | ||
}); | ||
it('equal test', function () { | ||
assert.equal(a.lex("2(7-4)3").toPostfix().postfixEval(),18); | ||
}); | ||
it('multiplication and exponential in series', function () { | ||
assert.equal(a.lex("2*7^2").toPostfix().postfixEval(),98); | ||
}); | ||
it('exponential and multiplication in series', function () { | ||
assert.equal(a.lex("2^5*2").toPostfix().postfixEval(),64); | ||
}); | ||
it('-3^2=-9', function () { | ||
assert.equal(a.lex("-3^2").toPostfix().postfixEval(),-9); | ||
}); | ||
it('3^2-2^2=5', function () { | ||
assert.equal(a.lex("3^2-2^2").toPostfix().postfixEval(),5); | ||
}); | ||
it('formula test', function () { | ||
@@ -47,6 +63,6 @@ assert.equal(a.lex("2").toPostfix().formulaEval(),2); | ||
it('check for constant inside Sigma', function () { | ||
assert.equal(a.lex("Sigma1,3,x",[{type:3,preced:0,ev:"x",show:"x",token:"x"}]).toPostfix().postfixEval({x:2}),6); | ||
assert.equal(a.lex("Sigma1,3,2",[{type:3,preced:0,ev:"x",show:"x",token:"x"}]).toPostfix().postfixEval({x:2}),6); | ||
}); | ||
it('check when arithmetic and n are present inside sigma', function () { | ||
assert.equal(a.lex("Sigma1,2,(1+n!)").toPostfix().postfixEval(),5); | ||
assert.equal(a.lex("Sigma1,2,n").toPostfix().postfixEval(),3); | ||
}); | ||
@@ -74,16 +90,2 @@ it('check when two parenthesis less functions are consecutive on one parameter', function () { | ||
}); | ||
it('check if expression ends with cos', function () { | ||
var str=a.eval("sin(2,3)"); | ||
var dc='' | ||
console.log(str); | ||
}); | ||
var date=new Date; | ||
for (var i=0;i<100000;i++) { | ||
var res=a.eval("15*3"); | ||
} | ||
console.log(new Date-date); | ||
console.log(res); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54839
1339
79