77. 数式パーサー¶
文字列で表現された数式をパースし、計算結果を取得する方法を学びます。
77.1 数式のパース¶
- 数式をパースし、計算結果を取得する次のような関数があります
| コード | 説明 |
|---|---|
double Eval(数式) |
数式をパースし、計算結果を double 型で返す。数式が不正な場合は NaN を返す |
Optional<double> EvalOpt(数式) |
数式をパースし、計算結果を double 型で返す。数式が不正な場合は none を返す |
- 数式内では次のような演算子や関数を使用できます:
+,-,*,/,%,^log2,log10,log,ln,exp,sqrt,sign,abs,min,max,sin,cos,tan,asin,acos,atan,sinh,cosh,tanh,asinh,acosh,atanh
# include <Siv3D.hpp>
void Main()
{
{
const String expression = U"100 + 10 * 2 + sqrt(9) + 10 * 0.2 ^2";
Print << Eval(expression);
Print << EvalOpt(expression);
}
{
// 不正な数式
const String expression = U"100 +";
Print << Eval(expression);
Print << EvalOpt(expression);
}
while (System::Update())
{
}
}
77.2 定数の追加¶
- 独自の定数など、新しい要素を数式内で使えるようにしたい場合は
MathParserクラスを使用します
# include <Siv3D.hpp>
void Main()
{
MathParser parser;
// 定数の追加
parser.setConstant(U"pi", Math::Pi);
parser.setConstant(U"x", 100);
// 数式の設定
parser.setExpression(U"x * pi");
Print << parser.eval();
Print << parser.evalOpt();
while (System::Update())
{
}
}
77.3 変数の追加¶
MathParserにdouble型の変数のアドレスを登録することで、数式内で変数を使用できます
# include <Siv3D.hpp>
void Main()
{
double x = 0.0;
MathParser parser;
parser.setVariable(U"x", &x);
parser.setExpression(U"100 + x");
for (int32 i = 0; i < 10; ++i)
{
x = (i * 0.1);
Print << parser.eval();
}
while (System::Update())
{
}
}
77.4 関数の追加¶
MathParserに独自の関数を登録できます
# include <Siv3D.hpp>
double CircleArea(double r)
{
return (Math::Pi * r * r);
}
double TriangleArea(double a, double b, double c)
{
double s = ((a + b + c) / 2.0);
return std::sqrt(s * (s - a) * (s - b) * (s - c));
}
void Main()
{
MathParser parser;
parser.setFunction(U"circleArea", CircleArea);
parser.setFunction(U"triangleArea", TriangleArea);
parser.setExpression(U"circleArea(10)");
Print << parser.eval();
parser.setExpression(U"triangleArea(3, 4, 5)");
Print << parser.eval();
while (System::Update())
{
}
}