By camino


2011-02-25 10:01:35 8 Comments

What is the best way to evaluate any custom math expression, for example

3+sqrt(5)+pow(3)+log(5)

I know that embedding Python into C++ can do that; is there any better way?

Thanks!

11 comments

@wildart 2012-03-01 06:33:21

muParserX is another C++ mathematical expression parser.

@templatetypedef 2011-02-25 10:06:06

There is no way to do this with an off-the-shelf standard library in C++, though there are many good parsing algorithms out there that will let you evaluate expressions like these.

If you'd like some references on good parsing algorithms, consider looking into Chapter 14 on expression parsing in Programming Abstractions in C++ (free and available online!), or consider looking into Dijkstra's shunting-yard algorithm. Both of the algorithms mentioned here are simple to implement and will let you evaluate expressions with relative ease.

If you're interested in some more hardcore tools for evaluating expressions, consider looking into the flex and GNU bison tools, which can build powerful parsers for these sorts of expressions. I believe that the bison documentation even shows you how to parse and evaluate arithmetic expressions, so you might have your work already done for you.

Hope this helps!

@a CVn 2011-02-25 10:33:19

Unrelated, but thanks for the tip about Programming Abstractions in C++!

@yas777 2016-08-25 20:15:04

The easiest way is to use an external library. The easiest one I've found is TinyExpr. It's written in C, so it should be very easy to call from C++. Also, it's only one source file and one header file. Very easy to integrate. You can get it here.

Solving your example problem is just:

#include "tinyexpr.h"
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Result: %f\n", te_interp("3+sqrt(5)+pow(3,2)+log(5)", 0));
    return 0;
}

I know that embedding Python into C++ can do that

You could do that, but you'd be pulling in a huge dependency to solve a simple problem.

@user5374653 2015-09-29 20:26:57

Not sure why 'pow' only has one parameter, but using the ExprTk library one can derive the following simple solution:

#include <cstdio>
#include <string>
#include "exprtk.hpp"

int main()
{
   typedef exprtk::expression<double> expression_t;
   typedef exprtk::parser<double>         parser_t;

   std::string expression_string = "3 + sqrt(5) + pow(3,2) + log(5)";

   expression_t expression;

   parser_t parser;

   if (parser.compile(expression_string,expression))
   {
     double result = expression.value();

     printf("Result: %19.15\n",result);
   }
   else
     printf("Error in expression\n.");

   return 0;
}

@Yury 2013-12-03 13:43:39

While searching a library for a similar task I found libmatheval. Seems to be a proper thing. Unfortunately, GPL, which is unacceptable for me.

@peastman 2013-04-30 22:54:27

Lepton is another C++ library that can do this. In addition to parsing and evaluating expressions, it also has some more advanced abilities. For example, it can compute analytic derivatives, and it can do some basic algebraic simplification of expressions. The library is quite small, and it's open source (MIT license).

@AndyUK 2012-02-23 19:41:37

I have developed a simple expression parser in C++ and Java. At the moment they only handle arithmetic operators +. -, / * but there is no reason they could not be extended to accommodate more functions.

These simple examples use the shunting yard algorithm to convert the expressions into reverse Polish notation and then another simple stack-based algorithm to actually evaulate the expression.

Code samples can be found here.

@Rhys Ulerich 2011-06-26 20:24:43

Here's an approach written for recent versions of Boost Spirit: http://agentzlerich.blogspot.com/2011/06/using-boost-spirit-21-to-evaluate.html

@aaz 2011-02-25 11:00:48

Boost.Spirit is a C++ parser library.

Examples:

@Tristram Gräbener 2011-02-25 12:27:15

+1 for boost.spirit. However your example points to 1.8 which differs considerably with later releases (with parsing now happening in boost::spirit::qi)

@aaz 2011-02-25 12:52:47

@Tristram – You're right. I linked to the current version from the distribution, but the other two links apply to the classic version only.

@lhf 2011-02-25 12:06:42

I've written a simple, easy-to-use, front-end to Lua for evaluating arithmetic expressions from C (and C++ of course). See http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#ae . See also OpenSouce C/C++ Math expression parser Library and What is a fast C or Objective-C math parser?

@Maxim Egorushkin 2011-02-25 12:23:25

Format a string like this:

#include <boost/lexical_cast.hpp>
#include <string>
#include <math.h>

extern "C" {
std::string evaluate() { return boost::lexical_cast<std::string>(3+sqrt(5)+pow(3)+log(5)); }
}

Invoke the C++ compiler to compile the above code into a shared library. Then load that shared library, resolve the address of evaluate, invoke it and get the result.

@aaz 2011-02-25 18:04:16

Why cast the result to string?

@Maxim Egorushkin 2011-02-25 18:07:28

You need to cast it to something because the type of the result the expression yields is unknown, string or a double.

Related Questions

Sponsored Content

37 Answered Questions

27 Answered Questions

[SOLVED] Easiest way to convert int to string in C++

13 Answered Questions

[SOLVED] What is the effect of extern "C" in C++?

22 Answered Questions

[SOLVED] What is the "-->" operator in C++?

29 Answered Questions

[SOLVED] What is the easiest way to make a C++ program crash?

  • 2011-12-12 22:26:23
  • jonathan topf
  • 63234 View
  • 310 Score
  • 29 Answer
  • Tags:   c++ crash

25 Answered Questions

[SOLVED] What is the easiest way to initialize a std::vector with hardcoded elements?

5 Answered Questions

[SOLVED] What is the difference between 'typedef' and 'using' in C++11?

9 Answered Questions

[SOLVED] What is a lambda expression in C++11?

11 Answered Questions

[SOLVED] Evaluating a mathematical expression in a string

  • 2010-03-03 13:10:39
  • Pieter
  • 98729 View
  • 99 Score
  • 11 Answer
  • Tags:   python math

Sponsored Content