Javaで数式の文字列を計算する方法

こんにちは、さるまりんです。

以前、Springの@Valueで計算式を使う方法について書かせてもらいました。

同じようなことがSpringではないJavaプログラムでもできないかな?単純に文字列を計算して結果が得られたら便利だなと思いました。

これ、exp4jというライブラリを使うことで可能になります。
github.comにあるexp4jの説明を見ると

exp4j is a mathematical expression evaluator for the Java programming language.

とあります。「Java言語用の数式を評価してくれるもの」です。

exp4jの公式情報はこちらです。GitHubはこちら

利用するにはこんな風にします。

まずは簡単に3×4+5を計算してみます。

Expression expression = new ExpressionBuilder("3*4+5").build();
double result = expression.evaluate();
System.out.println("result : " + result);

ExpressionBuilderのコンストラクタに文字列3*4+5を渡し、build()してExpression(数式表現)を作ります。
そしてそのevaluate()メソッドで評価、結果はdoubleで返されます。

上のプログラム3行を実行すると↓が出力されます。

result : 17.0

ちゃんと計算された結果ですね。

定数も使えます。

円の面積を求めるのはπr²、円周率×半径の2乗です。

これを計算するには

Expression expression = new ExpressionBuilder("pi*5^2").build();

piがπ(円周率)です。半径は5で計算しています。

同じように出力すると

result : 78.53981633974483

となります。

変数を使った表現も可能です。

辺a、bの間の角度がxの三角形の面積Sは

S = ½ ab sin(x)

です。

これをa=2b=5x=30°(ラジアンでπ/6)でやってみるとこうなります。

double radian = new ExpressionBuilder("pi/6").build().evaluate(); // 30°はπ/6
Expression expression = new ExpressionBuilder("1/2*a*b*sin(x)")
    .variables("a", "b", "x")
    .build();
expression.setVariable("a", 2);
expression.setVariable("b", 5);
expression.setVariable("x", radian);
double result = expression.evaluate();
System.out.println("result : " + result);

まず30°のラジアンでの値を計算しています。
続いて式を"1/2*a*b*sin(x)"で、variables("a", "b", "x")abxが変数であることを設定し、数式表現を作成しています。
その後setVariable()メソッドでそれぞれの変数に値を代入して、evaluate()で評価。

結果を出力すると

result : 2.4999999999999996

です。

あれ?sin(30°)½なので、½ × 2 × 5 × ½で本当な2.5のはず。

sin(π/6)を計算するときに誤差が出てしまっているようです。

floatdoubleを使うとこのような誤差が出てしまうことがあるので注意が必要です。何桁まで使うと決めてあげる必要がありそうですね。

これで単純な式だけでなく、いろんな数式の文字列を評価、計算することができます。

うまく使って便利になるといいなと思います。

読んでくださってありがとうございます。

それではまた!