Method for evaluating math expressions in Java

JavaMathFormula

Java Problem Overview


In one of my projects I want to add a feature where the user can provide in a formula, for example

sin (x + pi)/2 + 1

which I use in my Java app

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

How can I evaluate math expressions?

Java Solutions


Solution 1 - Java

There's also exp4j, an expression evaluator based on Dijkstra's Shunting Yard. It's freely available and redistributable under the Apache License 2.0, only about 25KB in size, and quite easy to use:

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

When using a newer API version like 0.4.8:

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

There's also a facility to use custom functions in exp4j.

Solution 2 - Java

To extend the list, I just have finished one, too:

https://github.com/uklimaschewski/EvalEx

EvalEx is a handy expression evaluator for Java, that allows to evaluate simple mathematical and boolean expressions.

Key Features:

  • Uses BigDecimal for calculation and result
  • Single class implementation, very compact
  • No dependencies to external libraries
  • Precision and rounding mode can be set
  • Supports variables
  • Standard boolean and mathematical operators
  • Standard basic mathematical and boolean functions
  • Custom functions and operators can be added at runtime

Examples:

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

Solution 3 - Java

It depends how complex are the expressions you want to eval but for simple ones, java has a javascript engine that works pretty well:

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

Solution 4 - Java

Nice math parser containing broad math collection - mXparser - please see the examples:

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

Result:

[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

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

Result:

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

For better understanding please follow mXparser tutorial and mXparser math collection.

Found recently - in case you would like to try the syntax (and see the advanced use case) you can download the Scalar Calculator app that is powered by mXparser.

Best regards

Solution 5 - Java

Adding another option to the list, I wrote Jep Java which gained a lot of popularity as an open source project on sourceforge.

It supports all the basic common tasks of expression parsing. But it also adds a lot of extendibility if you want to customize it. A lot of users have praised the library for being especially well written and easy to use. See the sourceforge reviews!

Here is a simple example with a single 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);

This will print "x + 1 = 11". You can change the value of variables and quickly evaluate the expression again.

I later also made the library available with a commercial license on the Singular Systems website.

Solution 6 - Java

I have a small-footprint yet very capable math evaluator which is completely unencumbered.

Primary Features
  • Basic math operators, with inferred precedence (+ - * × / ÷ % ^).
  • Explicit precedence with parenthesis.
  • Implicit multiplication of bracketed subexpressions.
  • Correct right-associativity of exponentials (power operator).
  • Direct support for hexadecimal numbers prefixed by 0x.
  • Constants and variables.
  • Extensible functions.
  • Extensible operators.
  • Tiny 20 KiB footprint.

Here's a simple example which calculates the middle column of the subsection of a text display (biased left).

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

Solution 7 - Java

I already have posted a similar answer here. I just wanted to say that I have been worked on a little library that supports math, boolean and string expression evaluation. Here is a small example :

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

If you are interested, it is available here.

Solution 8 - Java

You can check out ParserNG, a full fledged and extremely fast math expression parser which works in compile-evaluate phases. The compile phase parses/understands the expression. The evaluate phase solves it and is extremely fast.

I called it a parser, but it is more than that.

It evaluates math expressions, supports creation and usage of variables and constants, supports inbuilt and creation of custom functions, solves quadratic equations, simultaneous equations, Tartaglia's equations(a.x^3+b.x+c=0), solves also equations in a single variable by iterative means(using a number of fallback techniques), does basic statistics, differential calculus(includes its own implementation of a symbolic differentiator which it uses to spit out numerical values for derivatives at given values), solves numerical integrals.

It also handles matrices via a Function class and supports various matrix operations using matrix functions.

And that is not even all.

As an example, here is the parser doing some differential calculus:

MathExpression expr = new MathExpression("f(x)=x^3*ln(x); diff(f,3,1)"); 
System.out.println("result: " + expr.solve());

 result: 38.66253179403897

See more information about it in this stackoverflow answer

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEthan LeroyView Question on Stackoverflow
Solution 1 - JavafassegView Answer on Stackoverflow
Solution 2 - JavaUdo KlimaschewskiView Answer on Stackoverflow
Solution 3 - JavaSnicolasView Answer on Stackoverflow
Solution 4 - JavaLeroy KeganView Answer on Stackoverflow
Solution 5 - JavaNathan FunkView Answer on Stackoverflow
Solution 6 - JavaLawrence DolView Answer on Stackoverflow
Solution 7 - JavaSkyostView Answer on Stackoverflow
Solution 8 - JavagbenroscienceView Answer on Stackoverflow