¿Cuál es la mejor forma de evaluar expresiones matemáticas en C ++?

Cuál es la mejor manera de evaluar cualquier expresión matemática personalizada, por ejemplo

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

Sé que incrustar Python en C ++ puede hacer eso; ¿Hay alguna forma mejor?

¡Gracias!

Boost.Spirit es una biblioteca de analizador de C ++.

Ejemplos:

  • en su distribución: versión clásica y versión actual (busque “calc”);
  • en la wiki de Rosetta ;
  • algunas aplicaciones que lo usan.

No estoy seguro de por qué ‘pow’ solo tiene un parámetro, pero utilizando la biblioteca ExprTk se puede obtener la siguiente solución simple :

 #include  #include  #include "exprtk.hpp" int main() { typedef exprtk::expression expression_t; typedef exprtk::parser 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; } 

No hay forma de hacerlo con una biblioteca estándar estándar en C ++, aunque existen muchos algoritmos de análisis que le permitirán evaluar expresiones como estas.

Si desea algunas referencias sobre buenos algoritmos de análisis sintáctico, considere consultar el Capítulo 14 sobre el análisis de expresiones en Progtwigr abstracciones en C ++ (¡gratis y disponible en línea!), O considere estudiar el algoritmo de Dijkstra para el patio de maniobras . Ambos algoritmos mencionados aquí son simples de implementar y le permitirán evaluar expresiones con relativa facilidad.

Si le interesan algunas herramientas más duras para evaluar expresiones, considere buscar en las herramientas flex y bison GNU , que pueden construir analizadores potentes para este tipo de expresiones. Creo que la documentación de bison incluso muestra cómo analizar y evaluar expresiones aritméticas, por lo que puede que ya haya hecho su trabajo por usted.

¡Espero que esto ayude!

muParserX es otro analizador de expresiones matemáticas C ++.

He escrito un front-end sencillo y fácil de usar para Lua para evaluar expresiones aritméticas de C (y C ++ por supuesto). Ver http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#ae . Consulte también Analizador de expresiones matemáticas OpenSouce C / C ++ y ¿Qué es un analizador matemático rápido C u Objective-C?

Lepton es otra biblioteca de C ++ que puede hacer esto. Además de analizar y evaluar expresiones, también tiene algunas habilidades más avanzadas. Por ejemplo, puede calcular derivadas analíticas y puede hacer una simplificación algebraica básica de expresiones. La biblioteca es bastante pequeña y es de código abierto (licencia MIT).

Aquí hay un enfoque escrito para las versiones recientes de Boost Spirit: http://agentzlerich.blogspot.com/2011/06/using-boost-spirit-21-to-evaluate.html

Desarrollé un analizador de expresiones simples en C ++ y Java. Por el momento, solo manejan operadores aritméticos +. -, / * pero no hay ninguna razón por la que no puedan ampliarse para dar cabida a más funciones.

Estos ejemplos simples usan el algoritmo yarda de maniobras para convertir las expresiones en notación polaca inversa y luego otro algoritmo simple basado en la stack para realmente evaluar la expresión.

Los ejemplos de código se pueden encontrar aquí .

Mientras buscaba en una biblioteca una tarea similar, encontré libmatheval . Parece ser una cosa adecuada. Lamentablemente, GPL, que es inaceptable para mí.

Formatea una cadena como esta:

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

Invoque el comstackdor de C ++ para comstackr el código anterior en una biblioteca compartida. A continuación, cargue esa biblioteca compartida, resuelva la dirección de evaluate , iníciela y obtenga el resultado.

La forma más fácil es usar una biblioteca externa. El más fácil que he encontrado es TinyExpr . Está escrito en C, por lo que debería ser muy fácil llamar desde C ++. Además, es solo un archivo fuente y un archivo de encabezado. Muy fácil de integrar. Puedes obtenerlo aquí .

La solución de su problema de ejemplo es simplemente:

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

Sé que incrustar Python en C ++ puede hacer eso

Podrías hacer eso, pero tendrías una gran dependencia para resolver un problema simple.