用解释器评估计算但是值很大

时间:2013-09-05 17:37:23

标签: java biginteger beanshell

我正在使用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评估器?

1 个答案:

答案 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();

即使我没有将xy声明为BigDecimal,我仍然可以在add上致电x并传递y }。这是因为当BeanShell运行代码时,它知道xy的具体类型,并使用反射动态解析该方法。