【问题标题】:Finding the "discrete" difference between close floating point numbers找到接近浮点数之间的“离散”差异
【发布时间】:2012-01-16 11:56:19
【问题描述】:

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

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

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

假设y > xxy 仅相隔几步(例如,

(y-x) / x / eps

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

【问题讨论】:

标签: floating-point numerical x87


【解决方案1】:

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

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 用于比较浮点数。

【讨论】:

  • 只要数字> 0。仍然需要一些逻辑来覆盖负值和0(包括“-0”)。
  • +1,关于词典排序的有趣观察。不过,我真正想知道的是,这是否可能仅使用浮点算术运算。当我问这个问题时我使用的语言不支持将位模式重新解释为不同的类型。
  • @Szabolcs 你用的是什么语言?我用 C++ 编写了代码,但它应该可以在 C 和 D 中工作。
  • 我的问题并不是关于如何用那种语言来做,我只是好奇是否可以只使用浮点运算来完成,而不需要检查浮点数的位表示某种方式。我正在使用数学。即使不是直接回答我的问题,你的回答也很有趣,我很感激(特别是考虑到这个问题有多老)。
【解决方案2】:

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

首先使用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 表达。

【讨论】:

    猜你喜欢
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-06
    • 2021-12-06
    • 1970-01-01
    相关资源
    最近更新 更多