原文链接(http://www.singularsys.com/jep/doc/html/usage.html)
基本用法
入门指南
在您的项目中使用Jep包是非常容易的。以下步骤将使您快速入门。
- 下载Jep包
- 解包档案
- 将jep-java-x.x.x.jar文件(位于主目录下)移动到您选择的路径。
- 重要:要使java编译器在编译时能找到Jep类,编译器需要知道Jep类的位置。您需要在java IDE中设置jar归档的路径,以便编译器找到库(关于这一点,请参考您的IDE手册)。如果您没有使用IDE,您需要将.jar文件添加到您的CLASSPATH环境变量中(如果您不知道如何添加环境变量,请度这里)。您的CLASSPATH变量应包含像 C:\java\packages\jep-java-x.x.x.jar 这样的路径,这取决与您放置jar文件的位置。
- 在您的程序中包含以下代码
import com.singularsys.jep.Jep;
...
1: Jep jep = new Jep();
2: try {
3:jep.addVariable("x", 10);
4:jep.parse("x+1");
5:Object result = jep.evaluate();
6:
7:System.out.println("x + 1 = " + result);
8: } catch (JepException e) {
9:System.out.println("An error occurred: " + e.getMessage());
10: }
第1行创建了一个新的Jep解释器对象(javadoc对该类的描述)。第3行添加了变量“x”到解释器中,并将它的值初始化为10。在第4行和第5行,解释和求解表达式“x+1”。结果存储在result
中。最后,打印出结果,结果是“x + 1 = 11”被打印出来。
6.您应该能够编译您的应用程序,并在运行程序时看到打印的结果。
接下来是什么?浏览文档以了解Jep的所有功能。还可以查看示例applet的代码。而且不要忘记使用Javadocs作为参考!
错误处理
如果发生错误,则parse和evaluate方法抛出异常。解释方法抛出ParseException
实例,而求值方法抛出EvaluationException
实例。这两个类都是由JepException
扩展而来。所以,如果您不需要区分解释和求值错误,只需捕获JepException
。
异常类提供关于通过getMessage()方法发生的错误的信息。
默认设置
如果您创建了一个带有默认设置的Jep实例,您就可以使用函数部分列出的所有函数类解释表达式。
常量 | 说明 |
---|---|
pi | 3.1415… 圆的周长与其直径的比值(圆周率)(Math.PI) |
e | 2.718… 双精度欧拉常量(自然指数)(Math.E) |
true | 布尔常量(Boolean.TRUE) |
false | 布尔常量(Boolean.FALSE) |
i | 复数的虚部单位 |
求值方法
有三种求解表达式的方法可用:
- Object evaluate():求解最后一个解析表达式,并将结果作为一个对象返回。
- Object evaluate(Node root):求解由根节点传入的表达式,并将结果作为一个对象返回。
- double evaluateD():求解最后一个解释表达式,并将结果作为一个double值返回。如果结果不能被转换成double,则抛出
EvaluationException
异常。
您可能经常不知道表达式的结果是什么类型。例如,结果可以是Double,向量,布尔值,或字符串,这取决于解释的表达式。您可以根据操作符的情况来识别结果的类型,然后将结果转换到相应的类中。
快速反复求值
在不重复解析表达式的情况下,可以对表达式进行反复的求值,同时更改变量的值。当然,这比每次需要求解表达式时再重新解释表达式要快得多。
下面的代码展示了如何反复地调用addVariable(String, Object)
和 evaluate()
函数来改变变量的值和重新求解表达式。
// add variable to allow parsing
jep.addVariable("x", 0);
jep.parse("2*x-3");
// evaluate expression for x = 0 to x = 99
for (int i=0; i<100; i++) {// update the value of x
jep.addVariable("x", i);// print the result
System.out.println("Value at x = " + i + ": " + jep.evaluate());
}
您可以使用任何求值函数包括RealEvaluator
来快速反复求值。
小数算法
有了Jep 3,现在可以通过小数算法来求解表达式了。用于表示这种模式中的数据的数据类型是BigDecimal
,而不是double
。简单地使用下面的代码构建一个新的Jep实例:
import com.singularsys.jep.bigDecimals.BigDecComponents;
...
jep = new Jep(new BigDecComponents());
通过一个示例,最好地展示了精确度上的差异。当执行两个双精度类型的数的乘法时,10*0.09的结果为0.8999999999999999。但是,当使用小数算法和BigDecimal
类型来执行相同的计算时,10*0.09的结果为0.9。
如果您对执行高精度运算感兴趣,请参考这个文档的BigDecimal部分。
处理多个表达式
Jep可以同时处理多个表达式。一个简单的方法是在多个字符串上多次调用jep.parse()
方法。该方法返回一个表示表达式树的类型结点的对象。可以将这些结点存储起来供以后使用,并且可以用Jep.evaluate(Node n)
方法求值。
Jep jep = new Jep();
try {Node n1 = jep.parse("y=x^2");Node n2 = jep.parse("z=x+y");for (double x=0.0; x<=1.0; x+=0.1) {jep.addVariable("x", x);Object value1 = jep.evaluate(n1);Object value2 = jep.evaluate(n2);}
}
catch(JepException e) { }
另一个方法允许在单个字符串中包含所有表达式。可以用Jep.initMultiParse(String s)
,Jep.initMultiParse(Reader r)
和 continueParsing()
从单个字符串或Reader中读取一系列方程。方程是由分号隔开的。解释器使用initMultiParse
进行初始化,并且使用continueParsing()
依次读取表达式。
Jep jep = new Jep();
String s = "x=1; y=2; x+y";
jep.initMultiParse(s);
try {while ((Node n = jep.continueParsing()) != null) {Object res = jep.evaluate(n);}
}
catch (JepException e) { }
使用RealEvaluator快速求值
从Jep 3.2到Jep 3.3,用FastEvaluator
替换默认的StandardEvaluator
,从而实现了显著提升求值速度。然而,如果您的表达式只操作浮点数,您可以使用RealEvaluator
来代替RealEvatuator
,从而实现额外的性能提升。
RealEvaluator
可以通过Jep构造器加载
Jep jep = new Jep(new RealEvaluator());
或者通过在构建后设置求值器:
jep.setComponent(new RealEvaluator());
性能的提升依赖于诸如表达式、JVM和操作系统等因素。事实上,与FastEvaluator相比,速度提升了大约30%。