【发布时间】:2010-09-07 16:20:08
【问题描述】:
替代措辞:什么时候将 Double.MIN_VALUE 添加到 Java 中的 double不会导致不同的 Double 值? (请参阅下面 Jon Skeet 的评论)
SO question 关于 Java 中的最小 Double 值有一些在我看来是等效的答案。 Jon Skeet 的 answer 无疑是有效的,但他的解释并没有让我相信它与 Richard's answer 有何不同。
乔恩的回答使用以下内容:
double d = // your existing value;
long bits = Double.doubleToLongBits(d);
bits++;
d = Double.longBitsToDouble();
Richards 的回答提到了 Double.MIN_VALUE 的 JavaDoc
保持最小的常数 double 类型的正非零值, 2-1074。它等于十六进制 浮点字面量 0x0.0000000000001P-1022 也等于 到
Double.longBitsToDouble(0x1L)。
我的问题是,Double.logBitsToDouble(0x1L) 与 Jon 的 bits++; 有何不同?
Jon 的评论侧重于基本的浮点问题。
添加之间有区别 Double.MIN_VALUE 为双精度值, 并增加位模式 代表双。他们是 完全不同的操作,由于 浮点数的方式 被存储。如果你尝试添加一个非常 很小的数字到很大的数字, 差异可能很小 最接近的结果与 原本的。将 1 加到当前 然而,位模式总是 改变相应的浮动 点值,尽可能小 在该比例下可见的值。
我认为 Jon 增加一个长的“bits++”的方法与添加 Double.MIN_VALUE 没有任何区别。他们什么时候会产生不同的结果?
我编写了以下代码来测试差异。也许有人可以提供更多/更好的样本双数或使用循环来查找存在差异的数字。
double d = 3.14159269123456789; // sample double
long bits = Double.doubleToLongBits(d);
long bitsBefore = bits;
bits++;
long bitsAfter = bits;
long bitsDiff = bitsAfter - bitsBefore;
long bitsMinValue = Double.doubleToLongBits(Double.MIN_VALUE);
long bitsSmallValue = Double.doubleToLongBits(Double.longBitsToDouble(0x1L));
if (bitsMinValue == bitsSmallValue)
{
System.out.println("Double.doubleToLongBits(0x1L) is same as Double.doubleToLongBits(Double.MIN_VALUE)");
}
if (bitsDiff == bitsMinValue)
{
System.out.println("bits++ increments the same amount as Double.MIN_VALUE");
}
if (bitsDiff == bitsMinValue)
{
d = d + Double.MIN_VALUE;
System.out.println("Using Double.MIN_VALUE");
}
else
{
d = Double.longBitsToDouble(bits);
System.out.println("Using doubleToLongBits/bits++");
}
System.out.println("bits before: " + bitsBefore);
System.out.println("bits after: " + bitsAfter);
System.out.println("bits diff: " + bitsDiff);
System.out.println("bits Min value: " + bitsMinValue);
System.out.println("bits Small value: " + bitsSmallValue);
输出:
Double.doubleToLongBits(Double.longBitsToDouble(0x1L)) is same as Double.doubleToLongBits(Double.MIN_VALUE)
bits++ increments the same amount as Double.MIN_VALUE
Using doubleToLongBits/bits++
bits before: 4614256656636814345
bits after: 4614256656636814346
bits diff: 1
bits Min value: 1
bits Small value: 1
【问题讨论】:
标签: java floating-point