我认为 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 为了 ints:对于浮点值,简单地说就是 您可以添加标准“eps”以更改为下一个可表示的值 - “eps”始终取决于给定浮点值的指数。这就是为什么他们被称为 漂浮的 点,最后:)

然而,Java 1.6+ 提供 Math.nextAfter() 对于任何给定的,它返回 double, ,下一个或上一个可表示的 double.

在旧的 Java 版本上,你总是可以乱搞 Double.doubleToLongBits(), ,递增或递减其结果,然后转换回来 Double.longBitsToDouble();这将为您提供下一个或上一个代表 double 价值 - 在多数情况下:有一些特殊情况(NaN、无限值),因此不建议浮点新手这样做:)

其他提示

双倍有限的精度。min_normal是2e-1022。除非您将其添加到2E-1000的球场中,否则它将被丢弃。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top