找到紧密浮点数之间的“离散”差异

时间:2011-05-31 14:06:59

标签: floating-point numerical x87

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

计算机上可以显示离散数量的浮点数,因此我们可以按递增顺序枚举它们:f_1, f_2, f_3, ...。我希望在此列表中找到xy的距离(即它们分别是1,2,3,......或n个离散步骤?)

是否可以通过仅使用算术运算(+-*/)来实现,而不是查看二进制表示?我主要对x86如何工作感兴趣。

以下近似是否正确,假设y > xxy仅相隔几步(比如说,<100)? (可能不是......)

(y-x) / x / eps

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

2 个答案:

答案 0 :(得分: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
比较浮点数时使用

Such a technique

答案 1 :(得分: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&gt; x,计算从x到下一个2的幂的步数;然后计算获得2小于y的最大功率所需的步数;然后计算从那里到y需要多少步骤。我认为所有这些都很容易用eps来表达。