在Java中评估mathexpression式的方法

例如,在我的一个项目中,我想添加一个用户可以在公式中提供的function

sin (x + pi)/2 + 1 

我在我的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 } 

我如何评估mathexpression式?

还有一个exp4j ,一个基于Dijkstra调车场的表情评估器。 它可以在Apache许可证2.0下免费获得和重新发布,只有25kb的大小,而且非常容易使用。

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

还有一个在exp4j中使用自定义函数的工具 。

exp4j – 评估mathexpression式

玩的开心!

这取决于你想要评估的expression式有多复杂,但是对于简单的expression式,java有一个很好的javascript引擎:

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

为了扩大名单,我也完成了一个:

https://github.com/uklimaschewski/EvalEx

EvalEx是Java的一个方便的expression式评估器,允许评估简单的math和布尔expression式。

主要特征:

  • 使用BigDecimal进行计算和结果
  • 单class实施,非常紧凑
  • 没有依赖外部库
  • 精确和舍入模式可以设置
  • 支持variables
  • 标准的布尔运算符和math运算符
  • 标准的基本math和布尔函数
  • 自定义函数和运算符可以在运行时添加

例子:

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

我有一个小脚印,但非常有能力的math评估 ,是完全没有妨碍。

主要特点

  • 基本的math运算符,推断的优先级( + - * × / ÷ % ^ )。
  • 用括号显式优先。
  • 含括号的子expression式的隐式乘法。
  • 正确的指数权力关系(权力操作者)。
  • 直接支持前缀为0xhex数字。
  • 常量和variables。
  • 可扩展的function。
  • 可扩展的运营商。
  • 微小的20 KiB足迹。

这里是一个简单的例子,它计算文本显示的子部分的中间列(偏左)。

 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 

很好的mathparsing器,包含广泛的math集合 – mXparser – 请参阅示例:

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

结果:

 [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 

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

结果:

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

为了更好的理解,请按照mXparser教程和mXparsermath集合 。

最好的祝福