Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中数学表达式的求值方法_Java_Math_Formula - Fatal编程技术网

Java中数学表达式的求值方法

Java中数学表达式的求值方法,java,math,formula,Java,Math,Formula,例如,在我的一个项目中,我想添加一个用户可以在公式中提供的功能 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 *

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

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
}

如何计算数学表达式?

这取决于您要计算的表达式有多复杂,但对于简单的表达式,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 );
    }
}
还有一个基于的表达式计算器。它在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();
使用较新的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();

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

我占地面积小,但功能强大,完全不受阻碍

主要特征
  • 具有推断优先级的基本数学运算符(
    +
    -
    *
    ×
    /
    ÷
    %
    ^
  • 带括号的显式优先级
  • 括号内子表达式的隐式乘法
  • 更正指数的右关联性(幂运算符)
  • 直接支持前缀为
    0x
    的十六进制数字
  • 常量和变量
  • 可扩展函数
  • 可扩展运算符
  • 20千磅的小脚印
下面是一个简单的示例,它计算文本显示部分的中间列(偏左)


为了扩展列表,我也刚刚完成了一个:

EvalEx是一个方便的Java表达式计算器,它允许计算简单的数学表达式和布尔表达式

主要功能:

  • 使用BigDecimal进行计算和计算结果
  • 单类实现,非常紧凑
  • 不依赖于外部库
  • 可设置精度和舍入模式
  • 支持变量
  • 标准布尔和数学运算符
  • 标准基本数学和布尔函数
  • 可以在运行时添加自定义函数和运算符
示例:

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();
BigDecimal结果=null;
表达式=新表达式(“1+1/3”);
结果=表达式.eval():
表达式。设定精度(2);
结果=表达式.eval():
结果=新表达式(“(3.4+-4.1)/2”).eval();
结果=新表达式(“SQRT(a^2+b^2”)。带有(“a”、“2.4”)和(“b”、“9.253”).eval();
BigDecimal a=新的BigDecimal(“2.4”);
BigDecimal b=新的BigDecimal(“9.235”);
结果=新表达式(“SQRT(a^2+b^2”)。带有(“a”,a.)和(“b”,b).eval();
结果=新表达式(“2.4/PI”).setPrecision(128).setRoundingMode(RoundingMode.UP).eval();
结果=新表达式(“random()>0.5”).eval();

result=new Expression(“not(xNice math parser),包含广泛的数学集合--请参见示例:

例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
[mXparser-v.4.0.0] Res: f(pi) = 1.0
例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 1: sin(x + pi)/2 + 1 = 1.0
[mXparser-v.4.0.0] Res 2: sin(x + pi)/2 + 1 = 0.545351286587159
[mXparser-v.4.0.0] Res: f(pi) = 1.0
为了更好地理解,请遵循和

最近发现-如果您想尝试语法(并查看高级用例),可以下载mXparser支持的


致以最诚挚的问候

在列表中添加了另一个选项,我编写了Jep Java,它作为一个应用程序获得了广泛的欢迎

它支持表达式解析的所有基本常见任务。但是,如果您想自定义它,它还增加了许多可扩展性。许多用户称赞该库编写得特别好,而且易于使用。请参阅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”。您可以更改变量的值,并再次快速计算表达式


我后来还在上发布了该库的商业许可证。

我已经发布了类似的答案。我只是想说,我一直在开发一个支持数学、布尔和字符串表达式计算的小型库。下面是一个小示例:

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());
如果您感兴趣,它是可用的。

您可以查看一个功能齐全、速度极快的数学表达式解析器,它在编译-求值阶段工作。 编译阶段解析/理解表达式。求值阶段解决它,速度非常快

我称它为解析器,但它不止于此

它评估数学表达式,支持创建和使用变量和常量,支持内置和创建自定义函数,求解二次方程、联立方程、塔塔利亚方程(
a.x^3+b.x+c=0
),还通过迭代方式(使用大量回退技术)在单个变量中求解方程,做基础统计学,微分学(包括它自己的符号微分器的实现,它用它来吐出给定值的导数的数值),解数值积分

它还通过函数类处理矩阵,并使用矩阵函数支持各种矩阵操作

这还不是全部

作为一个示例,以下是解析器执行微分运算的过程:

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

 result: 38.66253179403897

有关它的更多信息,请参见

函数将比我在问题中使用的函数更复杂。它们将包含三角函数以及求幂等。我不认为JS eval()函数可以做到这一点。我不可能更喜欢这种技术。它很容易受到注入攻击,就像几乎所有这些基于泛型评估的技术一样。这种做法很糟糕。@JohnO那么你有什么建议吗?我真的不是web编程专家。@Snicolas-一般来说,我会使用一种对输入进行严格解析的工具,这将仅将其转换为数学表达式,不可能执行任意代码。@JohnO您可以将可以进入评估字符串的内容列为白名单。我喜欢这个示例,因为它是本机Java。此外,如果您不接受来自不可信来源的输入,也可以,因为isI已经使用了google,但前20个结果中的所有LIB都不是开放的ce也不是免费的。那么,你的谷歌fin是什么呢