Click here to Skip to main content
15,893,722 members
Articles / Programming Languages / C#
Tip/Trick

Math Parser .NET C#

Rate me:
Please Sign up or sign in to vote.
4.78/5 (42 votes)
28 Feb 2014GPL31 min read 184.5K   13.1K   71   37
This is light, fast and simple to understand mathematical parser designed in one class, which receives as input a mathematical expression (System.String) and returns the output value (System.Double)

Image 1

Introduction    

This is light, fast and simple to understand mathematical parser designed in one class, which receives as input a mathematical expression (System.String) and returns the output value (System.Double). For example, if your input string is "√(625)+25*(3/3)" then parser returns double value — 50. 

Background   

The idea was to create a string calculator for educational goals.  

How it work   

 Image 2

For more please look at the code, I tried to explain the work of the parser in the comments and how it can be changed and extended.  

Convert to RPN:

Image 3

* Input operators are replaced by the corresponding token (its necessary to distinguish unary from binary). 

Using the code  

Example:    

C#
public static void Main()
{
        MathParser parser = new MathParser();
    string s1 = "pi+5*5+5*3-5*5-5*3+1E1";
    string s2 = "sin(cos(tg(sh(ch(th(100))))))";
        bool isRadians = false;
        double d1 = parser.Parse(s1, isRadians);
    double d2 = parser.Parse(s2, isRadians);

        Console.WriteLine(d1); // 13.141592...
    Console.WriteLine(d2); // 0.0174524023974442
        Console.ReadKey(true);
}  

Features  

Ariphmetical operators :

  • () — parentheses;  
  • + —  plus (a + b); 
  • - — minus (a - b); 
  • * — multiplycation symbol (a * b); 
  • / — divide symbol (a / b); 
  • ^ — degree symbol (a ^ b).  

Functions :    

Trigonometric functions: 

  • sin(x);
  • cos(x);
  • tg(x);  
  • ctg(x). 

Hyperbolic functions:

  • sh(x);
  • ch(x);
  • th(x).  

Other functions: 
  • √(a), sqrt(a) — square root of a number; 
  • exp(x)  — exponential function (or just use e^x);  
  • (a)log(b) — logarithm; 
  • ln(x) — natural logarithm; 
  • abs(x) — absolute value.  

Constants:

  • pi — 3.14159265...;  
  • e — 2.71828183....  

Arguments of the trigonometric functions can be expressed as radians (true) or degrees (false) by sending appropriate bool value to parse method. Example (as radians):   

C#
parser.Parse("sin(90)", true);

Work with any char decimal separator in real number (regional settings).

New operators, functions and constants can be easily added to the code. 

This parser is simple (special designed in single class), convenient for the further implementation, expansion and modification.      

Points of Interest     

I better understand how parsers work and learned about the reverse-polish notation.

History

  • 2012/05/09: released the source code (1_0); 
  • 2012/06/07: optimized parser (1_2);    
  • 2014/02/28: rewritten version (1_4). 

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Kazakstan Kazakstan
The pragmatic software developer who has strong analytical and problem-solving skills aimed at improving the efficiency of the solutions implemented. His motto is 'quality, agile and performance'.

Prefers a systematic approach when solving a problem, so he thinks that every good developer, first of all, should be able to manage the complexity of a software system and produce a well-structured solution for a poorly defined problem.

Comments and Discussions

 
NewsSym Pin
Warren Harding16-Aug-12 20:32
Warren Harding16-Aug-12 20:32 
GeneralRe: Sym Pin
Yerzhan Kalzhani24-Aug-12 6:19
Yerzhan Kalzhani24-Aug-12 6:19 
QuestionBroken Image links Pin
fjdiewornncalwe7-Jun-12 4:53
professionalfjdiewornncalwe7-Jun-12 4:53 
AnswerRe: Broken Image links Pin
Yerzhan Kalzhani7-Jun-12 5:32
Yerzhan Kalzhani7-Jun-12 5:32 
GeneralPlease show and explain the code Pin
PIEBALDconsult14-May-12 13:51
mvePIEBALDconsult14-May-12 13:51 
GeneralRe: Please show and explain the code Pin
Yerzhan Kalzhani15-May-12 2:22
Yerzhan Kalzhani15-May-12 2:22 
GeneralRe: Please show and explain the code Pin
PIEBALDconsult15-May-12 7:03
mvePIEBALDconsult15-May-12 7:03 
SuggestionQuite complicated expression evaluator... Pin
Andreas Gieriet14-May-12 12:18
professionalAndreas Gieriet14-May-12 12:18 
Hello kirnbas,

your evaluator solution seems to me quite verbose and over-complicated.
You might have a look at Mathematical Expression Parser Using Coco/R[^] which provides two solutions:
A) writing a similar evaluator in about 100 lines of code by using http://ssw.jku.at/Coco/[^]
B) writing the same evaluator, but hand crafted, in less than 150 lines of code

BTW: I also find that you should elaborate more on why you show us your trick - why should I red that? E.g. if talking about localized number scheme, then you must talk about the consequences and how you deal with these:
- What number formats exist (decimal point, thousand separator, ...)?
- How you deal with the ambiguities (you have to also localize the list separator)?
- Run the localization on kk-KZ, ky-KZ, en-US, de-DE, de-CH, sv-SE, sv-FI

The quirks on localization is that the coma is usually used as list separator (e.g. f(a,b)) as well as thousand separator (en-US) or as decimal separator (de-DE).

One approach is to allow the ambiguity and let the parser read greedily (letting the user to solve ambiguities by adding parenthesis, e.g. f((3,14159),(1,4142135))).
Another approach is to make the language not ambiguous and also take the list separator from the CultureInfo class (beside the thousand separator and the decimal separator).

At least this topic is worth an elaboration. That's why my vote of 3.

Cheers
Andi
QuestionYou might want to elaborate on some of the inner workings, etc. Pin
ednrg14-May-12 8:07
ednrg14-May-12 8:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.