【问题标题】:IEEE-754 to Float in CIEEE-754 在 C 中浮动
【发布时间】:2013-06-12 09:04:06
【问题描述】:

我查看了许多类似的问题,但尚未找到解决方案。目前,-1.978569 是输出而不是 -7.9142766。我正在尝试匹配此页面的输出:http://babbage.cs.qc.cuny.edu/IEEE-754.old/32bit.html

感谢您的宝贵时间!

这是我的代码:

#include <stdio.h>
#include <math.h>

float IEEE_754_to_Float(const unsigned char b[4]) {
        int sign = (b[0] >> 7) ? -1 : 1;

        unsigned int fraction_bits = ((b[1] & 0x7F) << 16) + (b[2] << 8) + b[3];

        float fraction = 0.5f;
        unsigned char ii;
        for (ii = 0; ii < 24; ++ii)
                fraction += ldexpf((fraction_bits >> (23 - ii)) & 1, -(ii + 1));

        float significand = sign * fraction;

        return ldexpf(significand, 1);
}

int main() {
    unsigned char b[]={0xC0, 0xFD, 0x41, 0xC1};
    float f=IEEE_754_to_Float(b);
    printf("%f\n",f);
    return(0); }

【问题讨论】:

  • 您的程序在任何地方都没有使用浮点数的指数部分——这可能是个问题。
  • 欢迎来到 Stack Overflow。第一个问题好!
  • 我的指数计算代码错误,所以它返回 -inf 和 inf。这就是我删除它的原因。此页面上的其他代码有效。谢谢!感谢您的热烈欢迎,约翰!
  • 为什么不用union { unsigned char b[4]; float f } 或者只用memcpy(&amp;f, b, sizeof(f))

标签: c floating-point converter ieee-754


【解决方案1】:

你有一些错误。

首先,您忽略了指数字段。这些在第 30-23 位:

int exponentField = ((b[0] & 0x7F) << 1) + (b[1] >> 7);

其次,假设有一个前导 1 与显着。 (另外,只有 23 位有效位,所以您的循环实际上应该最多只有 23 位,但由于您只是添加 0,所以没有太大关系。)如果您将循环更改为以下内容:

float fraction = 1.0f;
unsigned char ii;
for (ii = 0; ii < 24; ++ii)
    fraction += ldexpf((fraction_bits >> (23 - ii)) & 1, -ii);

应该没问题。

最后,您需要考虑从exponentField 计算的指数:

return ldexpf(significand, exponentField - 127);

【讨论】:

  • +1,但对1.0f 的更改也必须伴随循环中的修复。指数应该只是-ii,而不是-(ii + 1),对吧?
  • 是的,修复了它,它可以工作(通过 codepad.org)。接得好。不过,我仍然必须说服自己为什么会这样:第一次你不想添加到小数点右边的第一位吗? ldexpf(1, 0) 是 1,而不是 0.5(二进制中的 0.1),对吗? (感谢 ++)
  • 根据 Carl Norum 的观点编辑了我的回复。
  • @John,仔细观察它是循环索引——它们实际上应该只有 0-22,减法应该是 22 - ii。尾数有 23 位,而不是 24 位。我想这比我建议的指数变化更好。就目前而言,第一次通过循环只是每次都加 0。
【解决方案2】:

指数位为 129,偏移 127 = 2。-1.978569 * (2 ** 2) = -7.9142766。

【讨论】:

  • ++。我还是有点疑惑,为什么他的正确答案接近 1/4。他从 0.5 开始,而不是 1.0。
  • 看起来像抵消错误:他的原始代码循环了 24 位尾数而不是 23 位。第一次通过循环时,它获取了指数的 LSB,即 1,并添加了 @ 987654321@,恰好是 0.5。
猜你喜欢
  • 1970-01-01
  • 2012-01-06
  • 2014-10-18
  • 1970-01-01
  • 2013-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多