web-dev-qa-db-fra.com

Méthode d'évaluation d'expressions mathématiques en Java

Dans l'un de mes projets, je souhaite ajouter une fonctionnalité permettant à l'utilisateur de fournir une formule, par exemple

sin (x + pi)/2 + 1

que j'utilise dans mon application Java

/**
 * The formula provided by the user
 */
private String formula; // = "sin (x + pi)/2 + 1"

/*
 * Evaluates the formula and computes the result by using the
 * given value for x
 */
public double calc(double x) {
    Formula f = new Formula(formula);
    f.setVar("x", x);
    return f.calc();
    // or something similar
}

Comment puis-je évaluer les expressions mathématiques?

45
Ethan Leroy

Il y a aussi exp4j , un évaluateur d'expression basé sur Dijkstra's Shunting Yard . Il est disponible gratuitement et redistribuable sous la licence Apache 2.0, sa taille ne dépasse pas 25 Ko et il est assez facile à utiliser:

Calculable calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
        .withVariable("x", varX)
        .withVariable("y", varY)
        .build()
double result1=calc.calculate();

Si vous utilisez une version plus récente de l'API telle que 0.4.8:

Expression calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
    .variable("x", x)
    .variable("y", y)
    .build();
double result1 = calc.evaluate();

Il existe également une possibilité d'utiliser des fonctions personnalisées dans exp4j .

20
fasseg

Cela dépend de la complexité des expressions à évaluer, mais pour les plus simples, Java a un moteur JavaScript qui fonctionne plutôt bien: 

import javax.script.*;
public class EvalScript {
public static void main(String[] args) throws Exception {
    // create a script engine manager
    ScriptEngineManager factory = new ScriptEngineManager();
    // create a JavaScript engine
    ScriptEngine engine = factory.getEngineByName("JavaScript");
    // evaluate JavaScript code from String
    Object obj = engine.eval("1+2");
    System.out.println( obj );
    }
}
8
Snicolas

Pour étendre la liste, j'en ai juste fini un:

https://github.com/uklimaschewski/EvalEx

EvalEx est un évaluateur d'expressions pratique pour Java, qui permet d'évaluer des expressions mathématiques et booléennes simples.

Principales caractéristiques:

  • Utilise BigDecimal pour le calcul et le résultat
  • Implémentation à classe unique, très compacte
  • Aucune dépendance à des bibliothèques externes
  • Le mode de précision et d'arrondi peut être réglé
  • Prend en charge les variables
  • Opérateurs booléens et mathématiques standard
  • Fonctions mathématiques de base et booléennes standard
  • Des fonctions et des opérateurs personnalisés peuvent être ajoutés à l'exécution

Exemples:

BigDecimal result = null;

Expression expression = new Expression("1+1/3");
result = expression.eval():
expression.setPrecision(2);
result = expression.eval():

result = new Expression("(3.4 + -4.1)/2").eval();

result = new Expression("SQRT(a^2 + b^2").with("a","2.4").and("b","9.253").eval();

BigDecimal a = new BigDecimal("2.4");
BigDecimal b = new BigDecimal("9.235");
result = new Expression("SQRT(a^2 + b^2").with("a",a).and("b",b).eval();

result = new Expression("2.4/PI").setPrecision(128).setRoundingMode(RoundingMode.UP).eval();

result = new Expression("random() > 0.5").eval();

result = new Expression("not(x<7 || sqrt(max(x,9)) <= 3))").with("x","22.9").eval();
8
Udo Klimaschewski

Analyseur mathématique sympa contenant une collection mathématique large - mXparser - veuillez consulter les exemples:

Exemple 1:

import org.mariuszgromada.math.mxparser.*;
...
...
Argument x = new Argument("x = pi");
Expression e = new Expression("sin(x + pi)/2 + 1", x);
mXparser.consolePrintln("Res 1: " + e.getExpressionString() + " = " + e.calculate());
x.setArgumentValue(2);
mXparser.consolePrintln("Res 2: " + e.getExpressionString() + " = " + e.calculate());

Résultat:

[mXparser-v.4.0.0] Res 1: sin(x + pi)/2 + 1 = 1.0
[mXparser-v.4.0.0] Res 2: sin(x + pi)/2 + 1 = 0.545351286587159

Exemple 2:

import org.mariuszgromada.math.mxparser.*;
...
...
Function f = new Function("f(x) = sin(x + pi)/2 + 1");
Expression e = new Expression("f(pi)", f);
mXparser.consolePrintln("Res: " + e.getExpressionString() + " = " + e.calculate());

Résultat:

[mXparser-v.4.0.0] Res: f(pi) = 1.0

Pour une meilleure compréhension, veuillez suivre tutoriel mXparser et collection mathématique mXparser .

Meilleures salutations

2
Leroy Kegan

Ajoutant une autre option à la liste, j’ai écrit Jep Java qui a gagné beaucoup de popularité en tant que projet open source sur sourceforge

Il prend en charge toutes les tâches courantes de base de l'analyse d'expression. Mais cela ajoute aussi beaucoup d'extensibilité si vous voulez le personnaliser. De nombreux utilisateurs ont félicité la bibliothèque pour sa qualité d'écriture et sa facilité d'utilisation. Voir les critiques de sourceforge!

Voici un exemple simple avec une seule variable:

import com.singularsys.jep.Jep;

Jep jep = new Jep();
jep.addVariable("x", 10);
jep.parse("x+1");
Object result = jep.evaluate();
System.out.println("x + 1 = " + result);

Cela affichera "x + 1 = 11". Vous pouvez modifier la valeur des variables et évaluer à nouveau rapidement l'expression. 

Par la suite, j'ai également rendu la bibliothèque disponible avec une licence commerciale sur le site Web de Singular Systems .

1
Nathan Funk

J'ai un faible encombrement et pourtant une grande capacité évaluateur en mathématiques qui n’est pas encombré.

Caractéristiques principales

  • Opérateurs mathématiques de base avec préséance inférée (+-*×/÷%^).
  • Priorité explicite avec parenthèses.
  • Multiplication implicite de sous-expressions entre crochets.
  • Bonne associativité à droite des exponentielles (opérateur de puissance).
  • Prise en charge directe des nombres hexadécimaux préfixés par 0x.
  • Constantes et variables.
  • Fonctions extensibles.
  • Opérateurs extensibles.
  • Minuscule empreinte de 20 Ko.

Voici un exemple simple qui calcule la colonne du milieu de la sous-section d’un affichage de texte (biaisée à gauche).

MathEval            math=new MathEval();

math.setVariable("Top",    5);
math.setVariable("Left",  20);
math.setVariable("Bottom",15);
math.setVariable("Right", 60);

System.out.println("Middle: "+math.evaluate("floor((Right+1-Left)/2)"));                        // 20
1
Lawrence Dol

J'ai déjà posté une réponse similaire ici . Je voulais juste dire que j'ai travaillé sur une petite bibliothèque qui prend en charge l'évaluation des mathématiques, des booléens et des expressions de chaîne. Voici un petit exemple:

String expression = "EXP(var)";
ExpressionEvaluator evaluator = new ExpressionEvaluator();
evaluator.putVariable(new Variable("var", VariableType.NUMBER, new BigDecimal(20)));

System.out.println("Value of exp(var) : " + evaluator.evaluate(expression).getValue());

Si vous êtes intéressé, il est disponible ici .

0
Skyost