有什么东西坏了,或者我不明白发生了什么?
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]
答案 0 :(得分:8)
一般的想法是首先将double转换为其长表示(使用doubleToLongBits
中的getRealBinary
),将长度增加1,最后将新long转换为double它代表通过longBitsToDouble
。
编辑:Java(自1.5开始)提供Math.ulp(double)
,我猜你可以用来直接计算下一个更高的值:x + Math.ulp(x)
。
答案 1 :(得分:7)
浮点数不会像整数类型那样在数字线上均匀分布。当你接近无限时,它们在0附近更密集地堆积并且相隔很远。因此,没有常量可以添加到浮点数以获得下一个浮点数。
答案 2 :(得分:4)
您的代码格式不正确。您尝试添加最小双精度值并期望结果与原始值不同。问题是double.MinValue非常小,结果是四舍五入的,不会受到影响。
建议阅读:http://en.wikipedia.org/wiki/Machine_epsilon
在Wikipedia上的文章中也有Java代码。根据定义,Epsilon是最小的数字,例如(X + eps * X!= X),而eps * X被称为“relative-epsilon”
答案 3 :(得分:3)
从Java 1.8开始,java.lang.Math.nextUp(double)
完全符合您的要求。还有java.lang.Math.nextDown(double)
的对面。
答案 4 :(得分:0)
如果您想使用BigDecimal类,还有BigDecimal.ulp()
方法。