爪哇:将 Double.MIN_NORMAL 添加到 double 不会改变数字
-
21-12-2019 - |
题
我认为 MIN_NORMAL 是一个可以添加到“正常”双精度值的值,并且数字会改变。例如。将 Double.MIN_NORMAL 添加到 0.1d ,您会得到一个与 0.1d 不同的值,但是我的理解是错误的:
public static void test(double val) {
if (val == (val - Double.MIN_NORMAL*1e50d))
System.out.printf("val == (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
else
System.out.printf("val != (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
}
其产生:
test(0.0d);
> val != (val - Double.MIN_NORMAL*1e50d) for val=0.00000000000000000000
test(1.0d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=1.00000000000000000000
test(0.1d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=0.10000000000000000000
有人请解释一下这里有什么违背我的逻辑的地方,即使我添加 MIN_NORMAL 乘以 1e50d,我仍然得到相同的数字。
我检查了二进制表示形式,发现 1 * Double.MIN_NORMAL 与 2 * Double.MIN_NORMAL 不同,但是从除零之外的任何值中减去这些值不会改变原始数字。
解决方案
MIN_NORMAL
正如 Javadoc 所说,只是最小的标准化 double
价值。但这并不意味着它是这样的 1
为了 int
s:对于浮点值,简单地说就是 不 您可以添加标准“eps”以更改为下一个可表示的值 - “eps”始终取决于给定浮点值的指数。这就是为什么他们被称为 漂浮的 点,最后:)
然而,Java 1.6+ 提供 Math.nextAfter()
对于任何给定的,它返回 double
, ,下一个或上一个可表示的 double
.
在旧的 Java 版本上,你总是可以乱搞 Double.doubleToLongBits()
, ,递增或递减其结果,然后转换回来 Double.longBitsToDouble()
;这将为您提供下一个或上一个代表 double
价值 - 在多数情况下:有一些特殊情况(NaN、无限值),因此不建议浮点新手这样做:)
其他提示
双倍有限的精度。min_normal是2e-1022。除非您将其添加到2E-1000的球场中,否则它将被丢弃。
不隶属于 StackOverflow