Jexl算术计算不准确

问题描述 投票:0回答:1

我有一个应用程序,它接收 JEXL 表达式列表,并使用从数据库检索的数据在循环中对它们进行计算。它确实有效,但计算不准确。例如,这个简单的公式:

a*b+c

其中 a 是整数,b - 浮点数,c - 双精度数。 值a = 600,b = 6.287和c = 102.245结果应该是3874.445,但JEXL给我3874.223。我检查了数百个样本,误差从 0.001% 到 0.3% 不等,但我从未得到确切的答案。 我的 JEXL 引擎看起来像这样:

JexlEngine jexl = new JexlBuilder().cache(2048).silent(false).strict(false).create();

我确实将 strict 设置为 false,因为某些数据可能为空,并且我不希望 JEXL 对此类数据感到厌烦。 有什么想法为什么会发生吗?

java calculation jexl
1个回答
0
投票

简短的答案是查看 IEEE 754 双精度二进制浮点格式。这意味着,即使在纯 Java 代码中,您也会得到如下结果:

double r = 600 * 6.287f + 102.245d; // r == 3874.4451953125

更长的答案是,您可以派生 JexlArithmetic,以便每个运算符将其参数转换为 BigDecimal 以获得精确的答案。作为示例,以下计算“正确”(注意 600b 使第一个数字成为 BigDecimal)。

  @Test
  public void testSO20230225() throws Exception {
    String src = "let a = 600b; let b = 6.287f; let c = 102.245d; a * b + c";
    final JexlBuilder builder = new JexlBuilder();
    final JexlEngine jexl = builder.create();
    JexlScript script = jexl.createScript(src);
    Object result = script.execute(null);
    double r = 3874.445d;
    Assert.assertEquals(r, ((Number) result).doubleValue(), 0.0000001d);
  }
© www.soinside.com 2019 - 2024. All rights reserved.