You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中不使用jeval如何从表达式字符串计算获取精确数值?

高精度表达式计算解决方案

问题根因

你遇到的精度问题是因为jeval底层默认使用double类型做运算,浮点数本身的存储特性导致0.1+0.2这类计算出现误差,你自己用BigDecimal硬编码运算可以解决问题,但没法适配动态表达式的场景。

现成工具库推荐

直接用成熟的表达式引擎即可,不需要自己手写全链路解析逻辑,目前主流支持BigDecimal高精度运算的工具如下:

AviatorScript(推荐)

阿里开源的高性能表达式引擎,原生支持一键开启高精度模式,自动处理所有运算的精度问题。
Maven依赖配置:

<dependency>
    <groupId>com.googlecode.aviator</groupId>
    <artifactId>aviator</artifactId>
    <version>5.4.1</version>
</dependency>

通用计算函数封装示例:

import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Options;
import java.math.MathContext;
import java.math.RoundingMode;

public class HighPrecisionCalc {
    // 初始化配置,全局只需要执行一次
    static {
        // 所有浮点数自动解析为BigDecimal,避免浮点精度丢失
        AviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_BIGDECIMAL, true);
        // 配置全局运算规则:精度保留16位,四舍五入,可按需调整
        AviatorEvaluator.setOption(Options.MATH_CONTEXT, new MathContext(16, RoundingMode.HALF_UP));
    }

    public static String calculate(String expression) {
        return AviatorEvaluator.execute(expression).toString();
    }

    public static void main(String[] args) {
        // 测试场景1
        System.out.println(calculate("(0.1+0.2)")); // 输出 0.3
        // 测试场景2
        System.out.println(calculate("(0.1+0.2)*10+15/3")); // 输出 8
    }
}

Apache Commons JEXL3

如果项目已经依赖commons系列组件,也可以选择JEXL3,通过配置算术解析器即可实现BigDecimal高精度运算,适配复杂表达式场景。

自定义实现思路(无第三方依赖场景)

如果不想引入额外jar包,可以自己实现通用解析逻辑,步骤如下:

  • 词法分析:拆分表达式为数字、运算符、括号三类token
  • 中缀转后缀:将常规写法的中缀表达式转为逆波兰表达式,处理运算符优先级、括号嵌套逻辑
  • 栈运算:遍历后缀表达式,数字直接转BigDecimal压栈,遇到运算符则弹出栈顶两个元素执行对应的BigDecimal运算,结果重新压栈
  • 结果输出:栈内最后剩余的元素就是最终计算结果

注意:自定义实现时必须指定除法的舍入模式,否则遇到除不尽的场景会直接抛出算术异常;所有数字必须用字符串构造BigDecimal,不能从double类型转换,否则构造阶段就会出现精度丢失。

内容的提问来源于stack exchange,提问作者flower

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:21:01