我正在使用Java中的BeanShell Interpreter来解决字符串计算问题。问题是我自己做了一些解析,这是解释器无法完成的,并将部分结果存储在BigInteger中。然后我将所有内容拼凑起来并给它解释,但我收到BigInteger.toPlainString()
的数字对interpreter.eval(...)
来说很大,因为我收到了以下错误消息:
Parse error at line 1, column 10 : Error or number too big for integer type: 2432902008176640000
Parse error at line 1, column 10 : Error or number too big for integer type: 2432902008176640000
计算字符串的构造如下:
BigDecimal x = new BigDecimal(/*very big number*/);
BigDecimal y = new BigDecimal(/*very big number*/);
String s = x.toPlainString() + "+" + y.toPlainString();
Interpreter i = new Interpreter();
i.eval("result = " + s);
s = i.get("result").toString();
我知道在这种情况下我可以通过提供的BigDecimal函数简单地添加数字,但在我的情况下,计算方式更复杂! 是否有可能的解决方法,所以我也可以使用带有大量数字的beanshell评估器?
答案 0 :(得分:2)
我假设你的场景真的更复杂,所以你不能在没有BeanShell的情况下做到这一点:
s = x.add(y).toString();
如果是这种情况,您应该知道可以直接从表达式访问BigDecimal
个对象:
i.set("x", x);
i.set("y", y);
i.eval("result = x.add(y);");
s = i.get("result").toString();
你甚至可以这样做:
String someBigNumber1, someBigNumber2;
// Set the number strings
i.set("xStr", someBigNumber1);
i.set("yStr", someBigNumber2);
i.eval("import java.math.BigDecimal;");
i.eval("result = new BigDecimal(xStr).add(new BigDecimal(yStr));");
s = i.get("result").toString();
BeanShell使用动态AST解析和反射来解释指令并根据具体类型解决方法:1)传递给它的东西和2)方法返回的东西。这与各种脚本语言具有未明确键入的var
变量的方式非常相似。例如,因为BeanShell正在使用解释器,它在运行时解析类型而不是“编译时”(在创建AST之外的BeanShell中不存在,这是解析,而不是编译),这在BeanShell中是合法的:
i.set("xStr", someBigNumber1);
i.set("yStr", someBigNumber2);
i.eval("import java.math.BigDecimal;");
i.eval("x = new BigDecimal(xStr);");
i.eval("y = new BigDecimal(yStr);");
i.eval("result = x.add(y);");
s = i.get("result").toString();
即使我没有将x
和y
声明为BigDecimal
,我仍然可以在add
上致电x
并传递y
}。这是因为当BeanShell运行代码时,它知道x
和y
的具体类型,并使用反射动态解析该方法。