在我的一个项目中,我想添加一个用户可以在公式中提供的功能,例如
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
}
我如何评估数学表达式?
答案 0 :(得分:21)
还有exp4j,一个基于Dijkstra's Shunting Yard
的表达式评估器。它在Apache License 2.0下免费提供并可再发行,大小仅为25KB,而且非常易于使用:
Calculable calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
.withVariable("x", varX)
.withVariable("y", varY)
.build()
double result1=calc.calculate();
使用较新的API版本时,如0.4.8
:
Expression calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)")
.variable("x", x)
.variable("y", y)
.build();
double result1 = calc.evaluate();
还可以在exp4j中使用自定义功能。
答案 1 :(得分:8)
这取决于你想要评估的表达式有多复杂,但对于简单的表达式,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 );
}
}
答案 2 :(得分:8)
为了扩展列表,我也完成了一个:
https://github.com/uklimaschewski/EvalEx
EvalEx是Java的一个方便的表达式计算器,它允许评估简单的数学和布尔表达式。
主要特点:
示例:
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();
答案 3 :(得分:2)
包含广泛数学集合的好数学解析器 - 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 tutorial和mXparser math collection。
祝你好运
答案 4 :(得分:2)
在列表中添加另一个选项,我写了Jep Java,它作为open source project on sourceforge获得了很多人气。
它支持表达式解析的所有基本常见任务。但是如果你想自定义它,它还增加了很多可扩展性。许多用户称赞图书馆写得特别好,易于使用。查看sourceforge评论!
这是一个带有单个变量的简单示例:
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);
这将打印“x + 1 = 11”。您可以更改变量的值并再次快速评估表达式。
我后来还使用Singular Systems website上的商业许可证提供了该库。
答案 5 :(得分:1)
我有一个小足迹但非常有能力的math evaluator完全不受阻碍。
+
-
*
×
/
÷
%
{{1} })。^
为前缀的十六进制数字。这是一个简单的例子,它计算文本显示的子部分的中间列(偏向左侧)。
0x
答案 6 :(得分:0)
我已经发布了类似的答案here。我只是想说我已经研究了一个支持数学,布尔值和字符串表达式求值的小库。这是一个小例子:
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());
如果您有兴趣,可以访问here。
答案 7 :(得分:0)
您可以签出ParserNG,这是一个成熟而又快速的数学表达式解析器,可在编译评估阶段使用。 编译阶段解析/理解该表达式。评估阶段可以解决该问题,而且速度非常快。
我称它为解析器,但不仅如此。
它可以评估数学表达式,支持变量和常量的创建和使用,支持自定义函数的内置和创建,可以求解二次方程,联立方程,塔塔格里亚方程(a.x^3+b.x+c=0
),还可以通过以下方式求解单个变量中的方程迭代方法(使用多种后备技术),进行基本统计,微积分(包括自己实现的符号微分器,并使用该微分器以给定值吐出导数的数值),求解数值积分。
它还通过Function类处理矩阵,并使用矩阵函数支持各种矩阵运算。
那还不是全部。
作为示例,下面是解析器进行的微分运算:
MathExpression expr = new MathExpression("f(x)=x^3*ln(x); diff(f,3,1)");
System.out.println("result: " + expr.solve());
result: 38.66253179403897
中查看有关此信息的更多信息