在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式的隐式乘法。
- 正确的指数权力关系(权力操作者)。
- 直接支持前缀为
0x
hex数字。 - 常量和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集合 。
最好的祝福