web-dev-qa-db-ja.com

Javaで数式を評価する方法

私のプロジェクトの1つで、ユーザーが式で提供できる機能を追加したい

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
}

数式を評価するにはどうすればよいですか?

49
Ethan Leroy

Dijkstra's Shunting Yard に基づいた式エバリュエーター exp4j もあります。 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();

0.4.8のような新しいAPIバージョンを使用する場合:

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

exp4j でカスタム関数を使用する機能もあります。

22
fasseg

評価したい式がどれだけ複雑かによって異なりますが、単純な式の場合、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 );
    }
}
9
Snicolas

リストを拡張するために、私もリストを完成させました。

https://github.com/uklimaschewski/EvalEx

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

リストに別のオプションを追加して、Jep Javaを作成しました。これは 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 Webサイト で商用ライセンスで利用できるようにしました。

2
Nathan Funk

幅広い数学コレクションを含む素敵な数学パーサー- 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チュートリアル および mXparser数学コレクション に従ってください。

宜しくお願いします

2
Leroy Kegan

フットプリントは小さくても非常に有能です math evaluator これは完全に邪魔されません。

主な機能

  • 推定優先順位を持つ基本的な数学演算子(+-*×/÷%^)。
  • 括弧付きの明示的な優先順位。
  • 括弧で囲まれた部分式の暗黙的な乗算。
  • 指数の正しい右結合性(べき乗演算子)。
  • 0xで始まる16進数の直接サポート。
  • 定数と変数。
  • 拡張可能な機能。
  • 拡張可能な演算子。
  • 小さな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
1
Lawrence Dol

私はすでに同様の答えを投稿しました 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

0
Skyost