0

这个想法是为了做与这个http://www.h-schmidt.net/FloatConverter/IEEE754.html几乎相同的事情

例如,如果我插入 357,我应该得到 0x43b28000

float unsignedToFloat( unsigned int x ) {
unsigned int result = 0;

return *(float*)&result;
}

但我该怎么做呢?

使用 c - printf 将 ieee 754 浮点数转换为十六进制

我看到了这个,但似乎没有任何好的解决方案。

4

2 回答 2

3

首先,如果x为零,则返回零。

接下来找到 中最高阶非零位的索引x。调用它i

如果i小于 24,则左移x23 - i获得归一化的有效数。现在清除位 23 以隐藏隐式位,并将位 23:30 设置为127 + i,这是偏置指数。返回结果。

否则,右移xi - 23通过截断获得归一化的有效位,并清除隐式位并如上所述设置指数。如果您想要的舍入模式是截断或舍入到负无穷大,那么您就完成了。否则,您将需要查看从x. 如果所需的舍入模式是舍入到无穷大并且设置了任何这些位,则将结果加一并返回。最后,如果所需的舍入模式是 round-to-nearest-ties-to-even(IEEE-754 默认),则有以下三种情况:

  • 尾随位是b0...:返回截断的结果。
  • 尾随位是b1000...:这是一个确切的中途情况。如果我们调用截断的结果t,则需要返回t + (t&1)t即只有在奇数时才四舍五入。
  • 尾随位是b1...1...:将截断的结果加一并返回。
于 2013-03-15T11:28:06.147 回答
1

我是这样做的:

更新

这个可以正确处理 0、INT_MIN 和舍入,AFAICT:

#define SIGN_MASK       (1 << 31)
#define HIDDEN_MASK     (1 << 23)
#define MANTISSA_MASK   (HIDDEN_MASK - 1)

#define INT_MIN 0x80000000
#define INT_MAX 0x7FFFFFFF

float intToFloat(int n)
{
    int sign;
    int exp;
    unsigned int half;

    if (n == 0)
         return 0.0f;

    if (n == INT_MIN)
        return -(float)(INT_MIN);

    sign = n < 0 ? SIGN_MASK : 0;
    if (sign)
        n = -n;

    if (!(n & ~(HIDDEN_MASK | MANTISSA_MASK)))
        for (exp = 0; !(n & HIDDEN_MASK); n <<= 1, exp--) ;
    else
    {
        half = 0;
        for (exp = 0; n & ~(HIDDEN_MASK | MANTISSA_MASK); exp++)
        {
            half >>= 1;
            if (n & 1)
                half |= 0x80000000;
            n >>= 1;
        }
        if (half > INT_MIN || ((half == INT_MIN) && (n & 1) != 0))
        {
            n++;
            if (n == 0x1000000)
            {
                n = 0; // or 0x800000, doesn't matter.
                exp++;
            }
        }

    }

    exp = (exp + 127 + 23) << 23;
    n = (n & MANTISSA_MASK) | sign | exp;

    return *((float *)&n);
}
于 2013-03-15T13:31:26.607 回答