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

Java JUnit测试乘法场景下如何选择Delta避免浮点数误差

关于JUnit测试浮点数乘法时delta值的选择

嘿,这个问题是浮点数精度的经典陷阱,我来帮你拆解清楚~

为什么会出现55000.00000000001的结果?

Java里的double是二进制浮点数,它没法精确表示所有十进制小数——比如1.1在二进制中是无限循环的小数,存储时只能近似取值。当你用这个近似值和50000.0相乘时,原本的微小误差就被放大,最终得到了接近但不等于55000的结果。

怎么选择合适的delta值?

JUnit的Assert.assertEquals(double expected, double actual, double delta)里的delta,是允许的最大误差范围:只要|actual - expected| ≤ delta,测试就会通过。选择delta可以遵循这几个原则:

  • 从业务场景出发:

    • 如果是处理金额(比如人民币),通常精确到分就足够,delta可以设为0.01;
    • 如果是科学计算或对精度要求高的场景,可以用更小的范围,比如1e-6(百万分之一)或1e-9(十亿分之一);
    • 如果你能明确业务允许的误差上限,直接用这个值作为delta最合理。
  • 结合浮点数的精度特性:
    double类型的有效精度大概是15-17位十进制数字,对于你的场景(结果是整数55000),实际误差只有1e-11左右,所以用1e-9这样的小delta完全足够,既不会放过真正的错误,也能兼容浮点数的正常精度误差。

  • 绝对不要用0作为delta:
    除非是完全精确的浮点数运算(比如2 * 0.5),否则几乎不可能让两个double值完全相等,用0必然会导致测试失败。

针对你的代码的优化示例

把你的JUnit断言改成这样就可以正常通过:

Assert.assertEquals(55000.0, javaResult, 1e-9);

额外建议:处理精确十进制计算的场景

如果你的代码是处理金额、货币这类需要完全精确十进制运算的业务,建议放弃double,改用java.math.BigDecimal。它可以精确表示十进制小数,运算时不会产生精度误差,测试时也不需要设置delta,直接断言相等即可。比如:

import java.math.BigDecimal;

public class MyClass {
    public static void main(String args[]) {
        BigDecimal A = new BigDecimal("50000.0");
        BigDecimal B = new BigDecimal("1.1");
        BigDecimal result = A.multiply(B);
        System.out.println("Result" + result); // 输出精确的55000.0
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:58:42