两个值之间唯一的`double`s数

时间:2015-11-06 00:32:03

标签: java floating-point precision numerical

我在下面提供了这个问题的答案(我没有找到'回答自己的问题'按钮)

原始问题

在Java中,我们有浮点类型double,它在内存中编码为64位。据此我们知道它可以承担最多2^64个可能的值,减去一些特殊值。我们可以列举所有这些。

给定Math.nextUp(d)Math.nextDown(d)的例程doubled将分别计算下一个更大和更小的double。现在我想知道如何计算从double doublea的{​​{1}}步数,即我的方法b应该如下工作:< / p>

difference(a,b)

......等等。

在Java OpenJDK中,提到的两个方法实现如下:

assume a fixed, given a.

            b = ....               | difference(a, b)
===========================================================
   a                               |  0
   Math.nextUp(a)                  |  1
   Math.nextDown(a)                |  1
   Math.nextUp(Math.nextUp(a))     |  2
   Math.nextDown(Math.nextDown(a)) |  2

public static double nextUp(double d) {
  if( Double.isNaN(d) || d == Double.POSITIVE_INFINITY)
    return d;
  else {
    d += 0.0d;
    return Double.longBitsToDouble(Double.doubleToRawLongBits(d) +
                                    ((d >= 0.0d)?+1L:-1L));
  }
}

我可以安全地做类似的事情,或者这只是工作,因为他们只考虑public static double nextDown(double d) { if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY) return d; else { if (d == 0.0) return -Double.MIN_VALUE; else return Double.longBitsToDouble(Double.doubleToRawLongBits(d) + ((d > 0.0d)?-1L:+1L)); } } 的增量和减量,也就是说,我可能遇到指数的问题?我强烈假设后一种情况,并想知道实现目标的正确方法是什么?

再一次:我希望这适用于任意1 s,即double应该返回从difference(1e-3,3.442e201)到{{{{}}}所需的Math.nextUp个步骤1}}。显然,只是迭代并计算1e-3在这种情况下不会做。

非常感谢,   托马斯。

回答问题

感谢@Thilo的评论,事实证明它实际上很容易计算差异。好吧,至少它是如此简单。

这是Java代码:

3.44e201

这里有一些基本的JUnit测试,以确认结果是否应该是:

Math.nextUp

我会感谢代码尚未涵盖的任何反指示或问题。

干杯,    托马斯。

1 个答案:

答案 0 :(得分:1)

看起来你可以只取两个值的doubleToRawLongBits并减去它们(加上一些额外的逻辑来处理符号,过零和Inf / NaN)。

由于所有nextUp都是加1,因此减法的结果应与步数一致。