webentwicklung-frage-antwort-db.com.de

Methode zur Auswertung mathematischer Ausdrücke in Java

In einem meiner Projekte möchte ich eine Funktion hinzufügen, die der Benutzer beispielsweise in einer Formel angeben kann

sin (x + pi)/2 + 1

die ich in meiner Java-App verwende

/**
 * 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
}

Wie kann ich mathematische Ausdrücke bewerten?

45
Ethan Leroy

Es gibt auch exp4j , einen Ausdrucksauswerter basierend auf Dijkstra's Shunting Yard . Es ist frei verfügbar und kann unter der Apache License 2.0 weiterverteilt werden. Es ist nur etwa 25 KB groß und sehr einfach zu verwenden:

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

Bei Verwendung einer neueren API-Version wie 0.4.8:

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

Es gibt auch eine Möglichkeit, benutzerdefinierte Funktionen in exp4j zu verwenden.

20
fasseg

Es hängt davon ab, wie komplex die Ausdrücke sind, die Sie auswerten möchten. Für einfache Ausdrücke verfügt Java über eine Javascript-Engine, die ziemlich gut funktioniert: 

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

Um die Liste zu erweitern, habe ich auch gerade eine beendet:

https://github.com/uklimaschewski/EvalEx

EvalEx ist ein praktischer Ausdrucksauswerter für Java, der die Auswertung einfacher mathematischer und boolescher Ausdrücke ermöglicht.

Hauptmerkmale:

  • Verwendet BigDecimal für die Berechnung und das Ergebnis
  • Einzelklassenimplementierung, sehr kompakt
  • Keine Abhängigkeiten zu externen Bibliotheken
  • Präzisions- und Rundungsmodus können eingestellt werden
  • Unterstützt Variablen
  • Boolesche und mathematische Standardoperatoren
  • Standardmäßige mathematische und boolesche Funktionen
  • Benutzerdefinierte Funktionen und Operatoren können zur Laufzeit hinzugefügt werden

Beispiele:

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

Netter Mathematik-Parser mit breiter Mathematik-Sammlung - mXparser - siehe Beispiele:

Beispiel 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());

Ergebnis:

[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

Beispiel 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());

Ergebnis:

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

Zum besseren Verständnis folgen Sie bitte der mXparser-Anleitung und mXparser math collection .

Freundliche Grüße

2
Leroy Kegan

Ich fügte eine weitere Option hinzu und schrieb Jep Java, das als Open Source-Projekt auf Sourceforge sehr populär wurde. 

Es unterstützt alle grundlegenden Aufgaben des Ausdrucks-Parsings. Es bietet jedoch auch eine große Erweiterbarkeit, wenn Sie es anpassen möchten. Viele Benutzer haben die Bibliothek dafür gelobt, dass sie besonders gut geschrieben und benutzerfreundlich ist. Sehen Sie sich die Sourceforge-Bewertungen an!

Hier ist ein einfaches Beispiel mit einer einzelnen Variablen:

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);

Dadurch wird "x + 1 = 11" gedruckt. Sie können den Wert von Variablen ändern und den Ausdruck schnell erneut auswerten. 

Später stellte ich die Bibliothek auch mit einer kommerziellen Lizenz auf der Singular Systems-Website zur Verfügung.

1
Nathan Funk

Ich habe einen kleinen, aber sehr fähigen math evaluator , der völlig unbelastet ist.

Hauptfunktionen

  • Grundlegende mathematische Operatoren mit abgeleiteter Priorität (+-*×/÷%^).
  • Explizite Rangfolge mit Klammern.
  • Implizite Multiplikation von eingeklammerten Unterausdrücken.
  • Korrigieren Sie die rechte Assoziativität von Exponentialen (Power Operator).
  • Direkte Unterstützung für Hexadezimalzahlen, denen 0x vorangestellt ist.
  • Konstanten und Variablen.
  • Erweiterbare Funktionen.
  • Erweiterbare Operatoren.
  • Kleiner 20-kiB-Fußabdruck.

Hier ist ein einfaches Beispiel, das die mittlere Spalte des Unterabschnitts einer Textanzeige berechnet (links vorgespannt).

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

Ich habe bereits eine ähnliche Antwort gepostet hier . Ich wollte nur sagen, dass ich an einer kleinen Bibliothek gearbeitet habe, die die Auswertung von mathematischen, booleschen und Zeichenfolgenausdrücken unterstützt. Hier ist ein kleines Beispiel:

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());

Bei Interesse steht Ihnen hier zur Verfügung.

0
Skyost