我在下面提供了这个问题的答案(我没有找到'回答自己的问题'按钮)
在Java中,我们有浮点类型double
,它在内存中编码为64位。据此我们知道它可以承担最多2^64
个可能的值,减去一些特殊值。我们可以列举所有这些。
给定Math.nextUp(d)
值Math.nextDown(d)
的例程double
和d
将分别计算下一个更大和更小的double
。现在我想知道如何计算从double
double
到a
的{{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
我会感谢代码尚未涵盖的任何反指示或问题。
干杯, 托马斯。
答案 0 :(得分:1)
看起来你可以只取两个值的doubleToRawLongBits
并减去它们(加上一些额外的逻辑来处理符号,过零和Inf / NaN)。
由于所有nextUp
都是加1,因此减法的结果应与步数一致。