public void CustomFunctions() { /* * This test demonstrates three ways of adding a function * to the Math Parser * * 1) directly pointing to the function * 2) lambda expression * 3) anonymous method */ MathParser parser = new MathParser(); //for long functions parser.LocalFunctions.Add("numberTimesTwo", NumberTimesTwoCustomFunction); // adding the function decimal resultA = parser.Parse("numberTimesTwo(3)"); //for short functions, use lambda expression, or anonymous method // 1) using lambda epxression (recommended) parser.LocalFunctions.Add("square", x => x[0] * x[0]); decimal resultB = parser.Parse("square(4)"); // 2) using anonymous method parser.LocalFunctions.Add("cube", delegate(decimal[] x) { return x[0] * x[0] * x[0]; }); decimal resultC = parser.Parse("cube(2)"); }
public void AdvancedArithmetics() { MathParser parser = new MathParser(); decimal resultA = parser.Parse("(2+3)(3+1)"); Assert.IsTrue(resultA == 20); }
public void BasicArithmetics() { MathParser parser = new MathParser(); decimal resultA = parser.Parse("5+2"); Assert.IsTrue(resultA == 7); decimal resultB = parser.Parse("5+2*3"); Assert.IsTrue(resultB == 11); }
public void ConditionStatements() { MathParser parser = new MathParser(); decimal resultA = parser.Parse("2+3=1+4"); Assert.IsTrue(resultA == 1); decimal resultB = parser.Parse("3+2>(2-1)"); Assert.IsTrue(resultB == 1); }
public void ProgrmaticallyAddVariables() { /* * when parsing an expression that requires * for instance a variable name declaration * or change, use ProgramaticallyParse(). */ MathParser parser = new MathParser(); // first way, using let varname = value decimal resultA = parser.ProgrammaticallyParse("let a = 2pi"); Assert.IsTrue(parser.Parse("a") == (decimal)Math.PI * 2); // second way, using varname := value decimal resultC = parser.ProgrammaticallyParse("b := 20"); Assert.IsTrue(parser.Parse("b") == 20); // third way, using let varname be value decimal resultD = parser.ProgrammaticallyParse("let c be 25"); Assert.IsTrue(resultD == 25); }
public void TestSpeedRegExVsStringReplce() { MathParser parser = new MathParser(); decimal t = parser.Parse("(3+2)(1+-2)(1--2)(1-+8)"); }
public void TestLongExpression() { MathParser parser = new MathParser(); decimal t = parser.Parse("4^2-2*3^2 +4"); }
protected void Page_Load(object sender, EventArgs e) { var parser = new MathParser(); var resultA = ""; #region LoadFuncs parser.LocalFunctions.Add("isprime", x => { if (x[0]%1 == 0) // check if it's an integer return Check.IsPrime((long) x[0]) ? 1 : 0; throw new ArgumentException("The input is not an integer"); }); parser.LocalFunctions.Add("isodd", x => { if (x[0]%1 == 0) // check if it's an integer return Check.IsOdd((long) x[0]) ? 1 : 0; throw new ArgumentException("The input is not an integer"); }); parser.LocalFunctions.Add("iseven", x => { if (x[0]%1 == 0) // check if it's an integer return Check.IsEven((long) x[0]) ? 1 : 0; throw new ArgumentException("The input is not an integer"); }); parser.LocalFunctions.Add("iscoprime", x => { if (x[0]%1 == 0) // check if it's an integer return Check.IsCoprime((long) x[0], (long) x[1]) ? 1 : 0; throw new ArgumentException("The input is not an integer"); }); parser.LocalFunctions.Add("gdc", x => { if (x[0]%1 == 0) // check if it's an integer return Get.Gdc((long) x[0], (long) x[1]); throw new ArgumentException("The input is not an integer"); }); parser.LocalFunctions.Add("lcm", x => { if (x[0]%1 == 0) // check if it's an integer return Get.Lcm((long) x[0], (long) x[1]); throw new ArgumentException("The input is not an integer"); }); parser.LocalFunctions.Add("mod", x => { if (x[0]%1 == 0) // check if it's an integer return Get.Mod((long) x[0], (long) x[1]); throw new ArgumentException("The input is not an integer"); }); parser.LocalFunctions.Add("mean", x => x.Sum() / x.Length); parser.LocalFunctions.Add("bindec", x => { var returnvalue = Converter.From(Base.Base2, x[0].ToString(parser.CultureInfo)).To(Base.Base10); resultA += @"<table style='border:1px solid green;margin:3px;float:left;'><tr><th>Binary</th><th>Decimal</th></tr> <tr><td>" + x[0].ToString(parser.CultureInfo) + @"</td><td>" + returnvalue + @"</td></tr></table><div style='clear:both;'></div>"; return Convert.ToDecimal(returnvalue); }); parser.LocalFunctions.Add("decbin", x => { var returnvalue = Converter.From(Base.Base10, x[0].ToString(CultureInfo.InvariantCulture)).To(Base.Base2); resultA += @"<table style='border:1px solid green;margin:3px;float:left;'><tr><th>Decimal</th><th>Binary</th></tr> <tr><td>" + x[0].ToString(CultureInfo.InvariantCulture) + @"</td><td>" + returnvalue + @"</td></tr></table><div style='clear:both;'></div>"; return Convert.ToDecimal(returnvalue); }); var isStart = false; var list = new List<decimal>(); //const bool isDone = false; parser.LocalFunctions.Add("table", x => { // remake this method, so that the the parser.LocalVariables["x"] < parser.LocalVariables["table_max"] // is in front of everything. then, we can reuse the newWindow check code GC.Collect(); if (x.Length < 3) { resultA += "Error: the function requires 3 parameters."; return 0; } if (x.Length == 4) { if (x[3] <= 0) { resultA += "Error: the step cannot be zero."; return 0; } } if (isStart == false) { parser.LocalVariables["x"] = x[1]; isStart = true; resultA += "<table style='border:1px solid green;margin:3px;float:left;'><tr><th>x</th><th>f(x)</th></tr>"; } if (parser.LocalVariables["x"] <= x[2]) { parser.Parse(Request["expression"]); resultA += "<tr><td>" +parser.LocalVariables["x"] + "</td><td>" + x[0] + "</td></tr>"; list.Add(x[0]); parser.LocalVariables["x"] += x.Length == 3 ? 1 : x[3]; //parser.Parse(Request["expression"]); //parser.LocalVariables["x"] += x.Length == 3 ? 1 : x[3]; } else { //IsDone = true; resultA += @"</table> <table style='border:1px solid green;margin:3px;float:right;'><tr><th>Sum</th><th>Mean</th><th>Median</th></tr> <tr><td>" + (double)list.SumOfListElements() + @"</td><td>" + (double)list.Mean() + @"</td><td>" + (double)list.Median() + @"</td></tr> </table> <br /> <br /> <br /> <a href='?expression=" + Request["expression"].Replace("table", "sum") + @"' style='margin:3px;float:right;'>(sum)</a><br /> <br /> <a href='?expression=seq()' style='margin:3px;float:right;'>(more)</a> <div style='clear:both;'></div>"; isStart = false; return 1; } return 1; }); parser.LocalFunctions.Add("sum", x => { // remake this method, so that the the parser.LocalVariables["x"] < parser.LocalVariables["table_max"] // is in front of everything. then, we can reuse the newWindow check code GC.Collect(); if (x.Length < 3) { resultA += "Error: the function requires 3 parameters."; return 0; } if (x.Length == 4) { if (x[3] <= 0) { resultA += "Error: the step cannot be zero."; return 0; } } if (isStart == false) { parser.LocalVariables["x"] = x[1]; isStart = true; resultA += "<table style='border:1px solid green;margin:3px;float:left;'><tr><th>x</th><th>f(x)</th></tr>"; } if (parser.LocalVariables["x"] <= x[2]) { list.Add(x[0]); resultA += "<tr><td>" + parser.LocalVariables["x"] + "</td><td>" + list.SumOfListElements() + "</td></tr>"; parser.LocalVariables["x"] += x.Length == 3 ? 1 : x[3]; parser.Parse(Request["expression"]); parser.LocalVariables["x"] += x.Length == 3 ? 1 : x[3]; } else { //IsDone = true; resultA += @"</table> <table style='border:1px solid green;margin:3px;float:right;'><tr><th>Sum</th><th>Mean</th><th>Median</th></tr> <tr><td>" + (double)list.SumOfListElements() + @"</td><td>" + (double)list.Mean() + @"</td><td>" + (double)list.Median() + @"</td></tr> </table> <br /> <br /> <br /> <a href='?expression="+ Request["expression"].Replace("sum","table")+ @"' style='margin:3px;float:right;'>(table)</a><br /> <br /> <a href='?expression=seq()' style='margin:3px;float:right;'>(more)</a> <div style='clear:both;'></div>"; isStart = false; return 1; } return 1; }); decimal upper = 0; decimal lower = 0; var isUpper = false; var isLower = false; var isParserDone = false; var isParserDone2 = false; const decimal h = 0.00000001M; // 0.00000000001M; parser.LocalFunctions.Add("d", x => { // remake this method, so that the the parser.LocalVariables["x"] < parser.LocalVariables["table_max"] // is in front of everything. then, we can reuse the newWindow check code GC.Collect(); if (x[0]==0 && x.Length < 2) { resultA += "Error: Please enter a function. The derivative is calculated with respect to x, i.e. d/dx(f(x))."; return 0; } if (x.Length < 2) { resultA += "Error: Please provide me with an x coordinate."; return 0; } if (!isUpper) { parser.LocalVariables["x"] = x[1] + h; if (!isParserDone) { isParserDone = true; parser.Parse(Request["expression"]); isParserDone = false; } if (isParserDone) { isUpper = true; upper = x[0]; } //IsParserDone = false; } if (!isLower && isUpper && isParserDone == false ) { //lower = x[0]; parser.LocalVariables["x"] = x[1]; if (!isParserDone2) { isParserDone2 = true; parser.Parse(Request["expression"]); isParserDone2 = false; //IsUpper = true; } if (isParserDone2) { isLower = true; lower = x[0]; } } //check the no. of times this is executed. if (isLower && isUpper && !isParserDone2) return Math.Round((upper - lower)/h); return 0; }); parser.LocalFunctions.Add("seq", x => { resultA += "This function is currently under development."; //under development. return 0; }); #endregion #region LoadVariables var ci = Thread.CurrentThread.CurrentCulture; var monthNo = ci.Calendar.GetMonth(DateTime.Today); var weekNo = ci.Calendar.GetWeekOfYear(DateTime.Today, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek ); var dayNo = ci.Calendar.GetDayOfYear(DateTime.Today); parser.LocalVariables.Add("month", monthNo); parser.LocalVariables.Add("week", weekNo); parser.LocalVariables.Add("day", dayNo); #endregion #region LoadOperators parser.OperatorList.Add("$"); parser.OperatorList.Add("isnot"); parser.OperatorList.Add("and"); parser.OperatorList.Add("or"); parser.OperatorAction.Add("isnot", (x, y) => (x != y) ? 1 : 0); parser.OperatorAction.Add("and", (x, y) => (x == 1 && y == 1) ? 1 : 0); parser.OperatorAction.Add("or", (x, y) => (x == 1 || y == 1) ? 1 : 0); parser.OperatorAction.Add("$", (x, y) => { if (x%1 != 0 || y%1 != 0) throw new ArgumentException("The input is not an integer"); var returnValue = (long)x ^ (long)y; resultA += @"<table style='border:1px solid green;margin:3px;float:left;'><tr><th>Decimal</th><th>Binary</th></tr> <tr><td style='text-align:center'>" + x.ToString(CultureInfo.InvariantCulture) + @"</td><td style='text-align:right'>" + Converter.From(Base.Base10, x.ToString(CultureInfo.InvariantCulture)).To(Base.Base2) + @"</td></tr> <tr><td style='text-align:center'>" + y.ToString(CultureInfo.InvariantCulture) + @"</td><td style='text-align:right'>" + Converter.From(Base.Base10, y.ToString(CultureInfo.InvariantCulture)).To(Base.Base2) + @"</td></tr> <tr><td style='text-align:center'>" + returnValue.ToString() + @"</td><td style='text-align:right'>" + Converter.From(Base.Base10, returnValue.ToString()).To(Base.Base2) + @"</td></tr> </table><div style='clear:both;'></div>"; return returnValue; }); //parser.OperatorAction["^"] = delegate(decimal x, decimal y) //{ // decimal returnValue = 1; // if (y == 0) // { // returnValue = 1; // } // else if (y == 1) // { // returnValue = x; // } // else if (y > 1) // { // for (int i = 0; i < y; i++) // { // returnValue *= x; // } // } // else if (y < 0) // { // for (int i = 0; i > y; i--) // { // returnValue *= 1/x; // } // } // return returnValue; //}; parser.LocalFunctions.Add("if", x => { if (x[0] == 1) return x[1]; return x.Length == 3 ? x[2] : 0; }); #endregion if (Request["expression"] == null) return; text.Value = Request["expression"]; parser.LocalVariables.Add("x", 0); try { result.Style.Add("border", "1px solid blue"); result.InnerHtml += "Result: " + parser.Parse(Request["expression"]).ToString(parser.CultureInfo); result.InnerHtml +="<br />" +resultA; } catch( Exception ex) { result.InnerHtml = ex.Message; } }
public void ExceptionCatching() { MathParser parser = new MathParser(); try { decimal result = parser.Parse("(-1"); Assert.Fail(); // fail if the above expression hasn't thrown an exception } catch (ArithmeticException) { } decimal tr = parser.Parse("rem(20,1,,,,)"); }
public void StrangeStuff() { MathParser parser = new MathParser(loadPreDefinedOperators: true); parser.OperatorList = new List<string>() { "times", "*", "dividedby", "/", "plus", "+", "minus", "-" }; parser.OperatorAction.Add("times", (x, y) => x * y); parser.OperatorAction.Add("dividedby", (x, y) => x / y); parser.OperatorAction.Add("plus", (x, y) => x + y); parser.OperatorAction.Add("minus", (x, y) => x - y); Debug.WriteLine(parser.Parse("5 plus 3 dividedby 2 times 3").ToString(parser.CultureInfo)); }
public void DetailedSpeedTestWithOptimization() { var mp = new MathParser(); mp.LocalVariables.Add("x", 5); var expr = "(3x+2)(2(2x+1))"; int itr = 3000; double creationTimeAndTokenization = BenchmarkUtil.Benchmark( () => mp.GetTokens(expr) ,1); var tokens = mp.GetTokens(expr); double parsingTime = BenchmarkUtil.Benchmark(() => mp.Parse(tokens), itr); double totalTime = creationTimeAndTokenization + parsingTime; //var mp = new MathParser(); //mp.LocalVariables.Add("x", 5); //var expr = "(3x+2)(2(2x+1))"; //int itr = 50; double parsingTime2 = BenchmarkUtil.Benchmark(() => mp.Parse(expr), itr); double totalTime2 = parsingTime2; }
private decimal IntegrateUsingSimpsonsRule( string expression, decimal lowerLimit, decimal upperLimit, decimal numberOfIntervals = 100000) { var parser = new MathParser(); var sizeOfInterval = ((upperLimit - lowerLimit)/numberOfIntervals); parser.LocalVariables["x"] = lowerLimit; var sum = parser.ProgrammaticallyParse(expression); for (var i = 1; i < numberOfIntervals; i += 2) { parser.LocalVariables["x"] = lowerLimit + sizeOfInterval*i; sum += 4*parser.ProgrammaticallyParse(expression); } for (var i = 2; i < numberOfIntervals - 1; i += 2) { parser.LocalVariables["x"] = lowerLimit + sizeOfInterval*i; sum += 2*parser.ProgrammaticallyParse(expression); } parser.LocalVariables["x"] = upperLimit; sum += parser.ProgrammaticallyParse(expression); var result = sum*sizeOfInterval/3; return result; }
public void CultureTest() { var mp = new MathParser(); var result = mp.Parse("3,21"); }
public void CommaPIBug() { var mp = new MathParser(); var result = mp.Parse("pi"); Assert.AreEqual(result, mp.LocalVariables["pi"]); }
public void Trigemoetry() { MathParser parser = new MathParser(); Assert.IsTrue(parser.Parse("cos(32) + 3") == (decimal)Math.Cos(32) + 3); }
public void CustomizeOperators() { // declaring the parser MathParser parser = new MathParser(); //customize the operator list parser.OperatorList = new List<string>() { "$", "%", "*", ":", "/", "+", "-", ">", "<", "=" }; // adding "dollar operator" to the OperatorAction list parser.OperatorAction.Add("$", delegate(decimal numA, decimal numB) { return numA * 2 + numB * 3; }); // parsing and comparing Assert.IsTrue(parser.Parse("3$2") == 3 * 2 + 3 * 2); }
private decimal IntegrateUsingRectangleMethod( string expression, decimal lowerLimit, decimal upperLimit, decimal numberOfIntervals = 100000) { decimal sum = 0; var parser = new MathParser(); var sizeOfInterval = ((upperLimit - lowerLimit)/numberOfIntervals); for (var i = 0; i < numberOfIntervals; i++) { parser.LocalVariables["x"] = lowerLimit + sizeOfInterval*i; sum += parser.ProgrammaticallyParse(expression)*sizeOfInterval; } var result = sum; return result; }
public void NegativeNumbers() { MathParser parser = new MathParser(); decimal resultA = parser.Parse("-1+1"); Assert.IsTrue(resultA == 0); decimal resultB = parser.Parse("--1"); Assert.IsTrue(resultB == 1); decimal resultC = parser.Parse("(-2)"); Assert.IsTrue(resultC == -2); decimal resultD = parser.Parse("(-2)(-2)"); Assert.IsTrue(resultD == 4); }
public void CustomFunctionsWithSeverelArguments() { /* * This example demonstrates the "anonymous method" way of adding * a function that can take more than one agument. */ MathParser parser = new MathParser(loadPreDefinedFunctions: false); //for long functions parser.LocalFunctions.Add("log", delegate(decimal[] input) // adding the function { // input[0] is the number // input[1] is the base if (input.Length == 1) { return (decimal)Math.Log((double)input[0]); } else if (input.Length == 2) { return (decimal)Math.Log((double)input[0], (double)input[1]); } else { return 0; // false } }); decimal resultA = parser.Parse("log(2)"); decimal resultB = parser.Parse("log(2,3)"); }
public void CultureIndepndenceCommaBug() { // this fixes the bug in MathParserLogic by adding CULTURE_INFO conversion // to _tokens[i] = LocalVariables[_tokens[i]].ToString(CULTURE_INFO); MathParser parser = new MathParser(); parser.LocalVariables.Add("x", 1.5M); decimal a = parser.Parse("x+3"); Assert.AreEqual(a, 4.5M); }
private static double EvaluateExpression(string expression, double x) { var parser = new MathParser {LocalVariables = {["x"] = (decimal) x}}; var result = parser.ProgrammaticallyParse(expression); return (double) result; }
public void SpeedTests() { var parser = new MathParser(); parser.LocalVariables.Add("x",10); var list = parser.GetTokens("(3x+2)"); //list.Add("("); //list.Add("3"); //list.Add("*"); //list.Add("x"); //list.Add("+"); //list.Add("2"); //list.Add(")"); // list = double time = BenchmarkUtil.Benchmark(() => parser.Parse("(3x+2)"), 25000); double time2 = BenchmarkUtil.Benchmark(() => parser.Parse(list), 25000); Assert.IsTrue(time >= time2); }
public bool domathwithlabels(string data, out int outv) { MathParser parser = new MathParser(); outv = 0; foreach (KeyValuePair<string, int> kvp in labels) { int v; parser.LocalVariables.Add(kvp.Key, kvp.Value); } try { //we only have ints in z80 so cast it to an int outv = (int)parser.ProgrammaticallyParse(data); } catch (Exception e) { Console.WriteLine("Math error"); return false; } return true; }
public void DecimalOperations() { //MathParser parser = new MathParser(new CultureInfo("sv-SE")); // uses "," as a decimal separator //decimal resultA = parser.Parse("0,245 + 0,3"); //decimal resultB = parser.Parse("-0,245 + 0,3"); //Assert.IsTrue(resultB == decimal.Parse("0,055", new CultureInfo("sv-SE"))); MathParser parserDefault = new MathParser(); // or new MathParser(new CultureInfo("en-US")) decimal resultC = parserDefault.Parse("0.245 + 0.3"); decimal resultD = parserDefault.Parse("-0.245 + 0.3"); Assert.IsTrue(resultD == decimal.Parse("0.055", parserDefault.CultureInfo)); }
private decimal IntegrateUsingTrapezoidalRule( string expression, decimal lowerLimit, decimal upperLimit, decimal numberOfIntervals = 100000) { var parser = new MathParser(); var sizeOfInterval = ((upperLimit - lowerLimit)/numberOfIntervals); parser.LocalVariables["x"] = lowerLimit; var sum = parser.ProgrammaticallyParse(expression); parser.LocalVariables["x"] = upperLimit; sum += parser.ProgrammaticallyParse(expression); for (var i = 1; i < numberOfIntervals; i++) { parser.LocalVariables["x"] = lowerLimit + i*sizeOfInterval; sum += parser.ProgrammaticallyParse(expression)*2; } var result = sum*sizeOfInterval/2; return result; }
public void DetailedSpeedTestWithOutOptimization() { var mp = new MathParser(); mp.LocalVariables.Add("x", 5); var expr = "(3x+2)(2(2x+1))"; int itr = 50; double parsingTime = BenchmarkUtil.Benchmark(() => mp.Parse(expr), itr); double totalTime = parsingTime; }
public void DifferentCultures() { MathParser parser = new MathParser(); }
public void ExecutionTime() { Stopwatch _timer = new Stopwatch(); _timer.Start(); MathParser parser = new MathParser(); decimal result = parser.Parse("5+2"); decimal result2 = parser.Parse("5+2*3*1+2((1-2)(2-3))"); decimal result3 = parser.Parse("5+2*3*1+2((1-2)(2-3))*-1"); _timer.Stop(); Debug.WriteLine("time to parser with MathParser: " + _timer.ElapsedMilliseconds); }
public void BuiltInFunctions() { MathParser parser = new MathParser(loadPreDefinedFunctions: true); decimal result = parser.Parse("round(21.333333333333)"); Assert.AreEqual(result, 21); decimal result2 = parser.Parse("pow(2,0)"); Assert.AreEqual(result2, 1); }
public BooleanParser(MathParser parser) { this.mathParser = parser; }
public bool domath(string data, out int outv) { MathParser parser = new MathParser(); outv = 0; foreach(KeyValuePair<string,string>kvp in equs) { int v; if (!isnumber(kvp.Value, out v)) return false; // we failed to turn this into a number parser.LocalVariables.Add(kvp.Key,(decimal)v); } try { //we only have ints in z80 so cast it to an int outv = (int)parser.ProgrammaticallyParse(data); } catch (Exception e) { Console.WriteLine("Math error"); return false; } return true; }