如何以最小增量改变double

Mar*_*gus 8 java double ieee-754

有什么东西坏了,或者我不明白发生了什么?

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));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

随着输出:

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]
Run Code Online (Sandbox Code Playgroud)

Mar*_*tos 8

一般的想法是首先将double转换为它的long表示(使用doubleToLongBits你已经完成的getRealBinary),将long增加1,最后将new long转换回它代表的double longBitsToDouble.

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

  • 从Java 1.6开始,有[`Math.nextAfter(start,direction)`](http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#nextAfter(double,%) 20double)),这是更可靠的.它甚至可以处理大约零等特殊情况. (3认同)

Mar*_*ers 7

浮点数不会像整数类型那样在数字线上均匀分布.当你接近无限时,它们在0附近更密集地堆积并且相隔很远.因此,没有常量可以添加到浮点数以获取下一个浮点数.