4

假设我有两个浮点数xy,它们的值非常接近。

在计算机上可以表示离散数量的浮点数,因此我们可以按升序枚举它们:f_1, f_2, f_3, .... 我希望在此列表中找到 和 的距离xy即它们是 1、2、3,... 还是n离散的步长?)

+-*/是否可以仅使用算术运算( )而不查看二进制表示来做到这一点?我主要对它在 x86 上的工作方式感兴趣。

下面的近似值是否正确,假设那个y > x和那个xy只有几个步骤(比如,< 100)相隔?(可能不是 ...)

(y-x) / x / eps

这里eps表示机器 epsilon。(机器 epsilon 是 1.0 和下一个最小浮点数之间的差。)

4

2 回答 2

3

浮点数按字典顺序排列,因此:

int steps(float a, float b){

  int ai = *(int*)&a;  // reinterpret as integer
  int bi = *(int*)&b;  // reinterpret as integer
  return bi - ai;
}

steps(5.0e-1, 5.0000054e-1);  // returns 9

在比较浮点数时使用这种技术。

于 2012-01-16T03:56:19.060 回答
1

我认为,您不必直接检查二进制表示,但您必须依靠它来获得准确的答案。

首先使用frexp()将 x 分解为指数exp和尾数。我相信下一个大于 x 的浮点数是x + eps * 2^(exp-1). (“-1”是因为 frexp 返回一个范围为 [1/2, 1) 而不是 [1, 2) 的尾数。)

如果 x 和 y 具有相同的指数,则基本完成。否则,您需要计算每个 2 的幂有多少步,即1.0/eps. 换句话说,2^n 和 2^(n+1) 之间的步数是1.0/eps.

因此,对于 y > x,计算从 x 到 2 的下一个幂的步数;然后计算需要多少步才能达到比 y 小 2 的最大幂;然后计算从那里到 y 还需要多少步。eps我认为,所有这些都可以很容易地用 来表达。

于 2011-05-31T16:59:32.340 回答