首页 > 解决方案 > 从没有 FPO 的定点整数重建 IEEE754 浮点二进制

问题描述

我有一个使用定点数的程序,因为我使用的 CPU 不支持 IEEE754 浮点数。

我首先通过查找指数将标准 IEEE754 转换为定点,然后通过手动访问内存中的所述 IEE754 浮点数的位来移动数字等等,我一直做得很好。转换后,我可以很好地进行定点计算。

但是,是否可以在没有 FPO 的情况下将定点(例如 Q15.16 整数)重建回 IEE754 浮点,以便支持 IEEE754/FPO 的 CPU 能够将其作为其本机浮点类型读取?是否有任何代码或示例说明了 CPU 的 FPO 单元如何在原始字节操作中实际进行这种转换,或者它只是一些无法在软件中完成的黑魔法?显然,我不是在寻找超精确的转换。

到目前为止,我看到的所有答案都使用 FPO。例如,首先计算已经需要 FPO 的 2^(-num_fraction_bits_in_fixed),然后将固定点缩放到该缩放因子。

编辑:通过使用 EOF 的答案作为基线,我能够创建以下代码片段,用于从定点整数重构 IEEE754 浮点数(在此示例中,定点是 Q31.32,存储在 INT64 中)。最后,我只是手动处理了 0 的情况,因为没有它,代码实际上会返回一个非常小的但仍然是非零值。

这是代码:

static INT32 count_exponent(UINT64 x)
{
    INT32 l = -33;
    for (UINT64 i = 0; i < 64; i++)
    {
        UINT64 test = 1ULL << i;
        if (x >= test)
            l++;
        else
            break;
    }
    return l;
}

UINT32 float_from_fix32(INT64 value)
{
    INT64 original_num = (INT64)value;
    UINT64 sign = 0;
    if (value < 0)
        sign = 1;

    // remove the signed bit if it's set
    INT64 unsigned_ver = value < 0 ? -value : value;

    // calculate mantissa
    int lz = nlz(unsigned_ver);
    UINT64 y = unsigned_ver << (lz + 1);

    // Our fixed-point is 64bits wide. 8 is the exponent bits for IEEE754
    UINT64 mantissa = y >> (33 + 8);

    // get the non-fractal bits, add the exponent bias ( 127 in IEEE754 )
    UINT64 non_fractal = (unsigned_ver >> 32);
    UINT64 exp = count_exponent(unsigned_ver) + 127;

    // construct the final IEEE754 float binary number
    // first add the last 23 bits (mantissa)
    UINT32 ret = mantissa;

    // add exponent
    ret |= (exp << 23);

    // special case of 0
    if(mantissa == 0 && non_fractal == 0)
        ret = 0;

    // add the sign if needed
    if (sign)
        ret |= 0x80000000;

    return ret;
}

标签: cfloating-pointieee-754fixed-point

解决方案


不失一般性,考虑 unsigned fixed-point number x,假设(这里失去一般性)定点格式中的每个数字都是(可以表示为)浮点格式的归一化浮点数:

1)查找前导零的数量n(可能有特殊的 CPU 指令可以快速完成此操作且无需(软件)循环)。

2) 将数字左移 ( y = x << n+1)(产生归一化的浮点尾数),然后右移 ( m = y >> (signbit+exponentbits)),这是浮点数的尾数。

3)取你的n,减去定点格式的非小数位数,加上浮点格式的指数偏差。将有偏的指数移动到定点结果的指数位位置。

4)如果原始数字不是无符号数,则在结果中设置符号位,如果该数字为负数。


a) 如果定点数是有符号的v,则转换为无符号数u,并单独保留符号s(可以直接复制到浮点数的符号位)。上述算法的无符号输入将是x = v < 0 ? -u : u

b)exponentbits取决于浮点数格式。对于 ieee754 32 位float,它是8.

c) 定点格式通常用整数n位表示数字,(从概念上)除以 的常数2^m。非小数位(如果存在)是n - mif的位n > m

d)exponent bias再次用浮点格式描述。对于 ieee754 32 位float,偏差为127.


推荐阅读