如何从 C 中的浮点数中提取有偏指数?

Posted

技术标签:

【中文标题】如何从 C 中的浮点数中提取有偏指数?【英文标题】:How can I extract the biased exponent from a floating point number in C? 【发布时间】:2017-02-03 02:01:04 【问题描述】:

我在从浮点数中查找有偏指数时遇到问题。我不明白为什么我从为参数输入的任何数字中返回 0。这是我的代码:

iFloat_t floatGetExp(iFloat_t x)

    return ((x >> 23) & 0x7f800000);

浮点数的指数是从位到 23-30,这就是为什么我向右移动 23 并且掩码为 0x7f800000。 例如,如果我给它传递了 248.875 的浮点数,则指数应该是 22。

【问题讨论】:

您屏蔽了错误的位,移位 23 位后,这些位位置将没有任何内容,并且您破坏了移位的结果。当您在移位后屏蔽掉位 0..23 时,您怎么能期望值 22? 哦,那我该如何进行正确的遮罩呢?换班前戴口罩吗? 您的掩码适用于值之前班次,而不是之后。所以,((x & 0x7f800000) > 23),或者,更好的是,((x >> 23) & 0xff) 都可以,但后者似乎更简单,更容易理解 [IMO] 除了符号位之外还需要屏蔽吗? @WeatherVane 符号位为 MSB,因此需要使用掩码来隔离指数。否则,转变产生sgn,exp 而不仅仅是exp 【参考方案1】:

((x >> 23) & 0x7f800000); 是移位和屏蔽顺序错误。


数学库 C 有一个检索指数的函数。这是便携的方式。

int floatGetExp(float x) 
    int expo;
    frexpf(x, &expo);  // fetch exponent  (0.5 <= significand < 1.0) * 2^expo
    if (x) expo -= 1;
    return expo;

假设iFloat_t x 的binary32 格式有4 种情况需要考虑:

无穷大/NaN,法线数,次法线,零。

iFloat_t floatGetExp(iFloat_t x) 
  uint32_t u = (uint32_t) x; // move into known type
  // mask off the biased exponent 
  int bias_expo = (u & 0x7F800000) >> 23;
  if (bias_exp == 0xFF) return TBD;  // inf or NaN
  if (bias_exp > 0) return bias_exp - 127; // the usual
  // handle sub-normal numbers
  if (u & 0x7FFFFFFF == 0) return 0; // zero
  bias_exp -= 126;
  while (u & 0x00400000 == 0) 
    u <<= 1;
    bias_exp--;
  
  return bias_exp;

【讨论】:

if (x) expo - 1; 什么都不做。我不确定它的用途是什么,但没有任何代码行我可以从中看到一个拼写错误使结果成为 IEEE 754 指数。 @PascalCuoq 是的 expo - 1 应该是 expo -= 1。当x == 0 时,指数无关紧要。 0 是常见的可接受结果。 - 与frexpf() 一样,当x != 0 时,从frexpf() 派生的指数为1,因为它的有效数字在[.5, 1.0) 的范围内,并且许多人希望指数匹配范围内的有效数字[1.0, 2.0) .

以上是关于如何从 C 中的浮点数中提取有偏指数?的主要内容,如果未能解决你的问题,请参考以下文章

C中的浮点数与预期略有不同

关于IEEE754中的浮点数的阶码的表示问题

C语言学习|判断语句中的浮点数比较问题

Printf 用于 c 中的浮点数

Lua和C++中的浮点数的比较

Lua和C++中的浮点数的比较