为什么这个断言在 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),断言也通过了。
有人可以更详细地解释一下吗:
- 为什么断言在 eps = 1.0E-13 时通过,但在 eps = 1.0E-14 时失败
- 为什么断言在 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] 提升。
确定每个位组合代表的实际值的方程式是:
通过这个公式,最小值可以用
表示3ff0 0000 0000 000116 => 1.0000000000000002
要获得更好的解释,请参阅此 wiki 页面 Double-precision floating-point format
关于java - 比较 Java 中的小 double 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41696099/