使用 C 查找下一个 IEEE 754 可表示数(朝向 -INF)?

use*_*396 4 c floating-point representation ieee-754 floating-point-precision

我正在尝试编写一个函数,该函数接受一个 32 位浮点数(已从 32 位二进制字符串转换而来)并以 32 位二进制返回先前可表示的浮点数。到目前为止,我已经从二进制转换为向下浮动,但是我在理解如何找到下一个可表示的 IEEE 754 值时遇到了麻烦。你不能只减去可能的最小可表示值(000 0000 0000 0000 0000 0001)吗?另外,在找到最接近的可表示二进制值之前从 IEEE 754 转换为 Float 有什么好处(如果有的话)?

到目前为止,我只有一个将浮点数转换为简单精度 32 位二进制的函数。我会包括我的代码,但这是给学校的,所以我觉得把它放在网上/获得明确的更正和建议是不确定的。

chu*_*ica 5

问:你不能只减去可能的最小可表示值吗?
答:不可以。浮点数按对数分布,而不是线性分布。减去任何固定值(如 0.000001)对大值没有影响,float而对小float值有过大的影响。

问:在找到最接近的可表示二进制值之前,从 IEEE 754 转换为 Float 有什么好处?
答:“IEEE 754”到“Float”通常是相同的类型 - 不会发生转换。两者都是 32 位数字表示。

以下取决于float是 IEEE 754 binary32。它还依赖于int32_tand的字节序float来匹配。当输入为 时,它返回NaN-INF

float nextdown(float x) {
  union {
    float x;
    int32_t i;
  } u;
  u.x = x;
  if (u.i > 0) {
    u.i--;
  }
  else if (u.i < 0) {
    u.i++;
  }
  else {
    u.i = 0x80000001;
  }
  return u.x;
}
Run Code Online (Sandbox Code Playgroud)

以上不能很好地处理 NaN。一个简单的额外测试:

float nextdown(float x) {
  // catch NaN
  if (x != x) return x;

  union {
    float x;
    int32_t i;
  } u;
  ...
Run Code Online (Sandbox Code Playgroud)

注意:OP 所需的功能与<math.h> nextafterf(x,-1.0f/0.0f)用于测试此代码的功能几乎完全相同。NaN 和 -INF 的差异。

  • @user3614396 `nextafterf()` 接受 2 个参数 `x` 和 `y`。它返回 _next_ 可表示的在 `y` 方向上最接近 `x` 的 `float`。所以 `nextafterf(1.0f, 2.0f)` 返回一个刚好大于 1.0f 的数字。`nextafterf(1.0f, 0.0f)` 返回一个小于 1.0f 的数字。`nextafterf(1.0f, 1.0f)` 返回 `1.0f`。 (2认同)