java - 比较 Java 中的小 double 值

标签 java floating-point precision

为什么这个断言在 Java 中失败:

    double eps = 0.00000000000001;
    double ten = 10.0;
    double result = (ten - (ten - eps));
    Assert.assertTrue(result <= eps);

如果我在 eps 中的数字 1 之前删除一个零,则断言通过。我认为这与浮点实现有关,但我不确定具体如何。

此外,如果我用 2 替换数字 1(如 0.00000000000002),断言也会通过。在这种情况下,我什至可以在数字 2 之前添加更多的零,测试仍然会通过。我尝试使用 Double.MIN_VALUE (4.9E-324),断言也通过了。

有人可以更详细地解释一下吗:

  1. 为什么断言在 eps = 1.0E-13 时通过,但在 eps = 1.0E-14 时失败
  2. 为什么断言在 eps = Double.MIN_VALUE (4.9E-324) 时通过,而不是 eps = 1.0E-14

编辑:当我将 eps 增加到 1.0E-8 时,断言也会失败:double eps = 0.00000001;

最佳答案

这是因为表示 double 类型的字节组织所致。

如下图所示,它是一个 64 位结构。位 [b0 .. b51] 被“连接”并通过指数 [b52 .. b62] 提升。

Representation of the double type

确定每个位组合代表的实际值的方程式是:

Double formula

通过这个公式,最小值可以用

表示
3ff0 0000 0000 000116   =>  1.0000000000000002

要获得更好的解释,请参阅此 wiki 页面 Double-precision floating-point format

关于java - 比较 Java 中的小 double 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41696099/

相关文章:

java - 为什么将类定义为 final 会提高 JVM 性能?

C - 指向 double 和 double 组的指针之间的细微差别。将一个转换为另一个?

python - 如何在 Python 2.7 中检查字符串是(int 还是 float)

sql-server-2005 - SQL Server : Calculation with numeric literals

减法时的 MATLAB 精度

python - 100位 float python

java - 无法将 MP3 文件移动到其他文件夹

java - 我想要通用类的 "Class<T>"和 "Class variable"

java - 如何从 scala 案例类生成 java 数组

Matlab sin(pi) 及其与机器 epsilon 的关系