9

有什么东西坏了还是我不明白发生了什么?

static String getRealBinary(double val) {
    long tmp = Double.doubleToLongBits(val);
    StringBuilder sb = new StringBuilder();

    for (long n = 64; --n > 0; tmp >>= 1)
        if ((tmp & 1) == 0)
            sb.insert(0, ('0'));
        else
            sb.insert(0, ('1'));

    sb.insert(0, '[').insert(2, "] [").insert(16, "] [").append(']');
    return sb.toString();
}

public static void main(String[] argv) {
    for (int j = 3; --j >= 0;) {
        double d = j;
        for (int i = 3; --i >= 0;) {
            d += Double.MIN_VALUE;
            System.out.println(d +getRealBinary(d));
        }
    }
}

带输出:

2.0[1] [00000000000] [000000000000000000000000000000000000000000000000000]
2.0[1] [00000000000] [000000000000000000000000000000000000000000000000000]
2.0[1] [00000000000] [000000000000000000000000000000000000000000000000000]
1.0[0] [11111111110] [000000000000000000000000000000000000000000000000000]
1.0[0] [11111111110] [000000000000000000000000000000000000000000000000000]
1.0[0] [11111111110] [000000000000000000000000000000000000000000000000000]
4.9E-324[0] [00000000000] [000000000000000000000000000000000000000000000000001]
1.0E-323[0] [00000000000] [000000000000000000000000000000000000000000000000010]
1.5E-323[0] [00000000000] [000000000000000000000000000000000000000000000000011]
4

5 回答 5

9

总体思路是首先将 double 转换为其 long 表示形式(使用doubleToLongBits您在 中所做的getRealBinary),将该 long 增加 1,最后将新的 long 转换回它表示的longBitsToDoubledouble

编辑:Java(自 1.5 起)提供Math.ulp(double),我猜您可以使用它直接计算下一个更高的值x + Math.ulp(x)

于 2010-10-10T13:24:14.753 回答
7

浮点数不像整数类型那样在数轴上均匀分布。当你接近无穷大时,它们在 0 附近更密集,并且相距很远。因此,没有常数可以添加到浮点数以得到下一个浮点数。

于 2010-10-10T13:21:56.367 回答
4

您的代码格式不正确。您尝试添加最小双精度值并期望结果与原始值不同。问题是 double.MinValue 太小以至于结果被四舍五入并且不会受到影响。

建议阅读:http ://en.wikipedia.org/wiki/Machine_epsilon

在 Wikipedia 文章中也有 Java 代码。根据定义,Epsilon 是最小的数,例如 (X + eps * X != X),而 eps*X 称为“相对-epsilon”

于 2010-10-10T13:26:50.920 回答
4

从 Java 1.8 开始,您就可以java.lang.Math.nextUp(double)完全按照您的意愿行事。也有相反的java.lang.Math.nextDown(double)

于 2017-05-17T13:30:25.847 回答
0

如果您想使用 BigDecimal 类,也有该BigDecimal.ulp()方法。

于 2013-09-18T10:06:37.990 回答