浮动到固定转换

时间:2015-02-12 17:13:14

标签: c++ math floating-point fixed-point

这是一个基本问题,但我很困惑。

我有一个格式为1.4.12的寄存器。意思是它需要一个浮点数并且取范围-15.9999 - 15.9999,这是正确的,还是有多少9个?我对范围感到困惑。

我需要将c ++ float转换为定点并将其放入寄存器中?在C中有没有任何std :: library可以做到这一点?如果没有,有人可以指出我的标准代码吗?

另外,如何将fixed修改为float会很好吗?

2 个答案:

答案 0 :(得分:3)

自己做这件事很简单:

typedef int32_t fixed;

fixed float_to_fixed(float x)
{
    return (fixed)(x * 65536.0f / 16.0f);
}

请注意,这没有范围检查,因此如果x可能超出固定点类型的有效范围,那么您可能需要添加一些检查,并根据需要进行饱和或抛出错误。

同样适用于其他方向的转换:

float fixed_to_float(fixed x)
{
    return (float)x * 16.0f / 65536.0f;
}

(当然这个不需要任何范围检查。)

答案 1 :(得分:0)

如果需要使用定点,则必须实现加法和乘法运算。在这种情况下,您需要担心为小数部分分配了多少位以及为整数部分分配了多少位。然后,您可以根据自己的喜好进行“移位”操作。

在下面的代码段中,我通过为小数部分分配22位和为整数部分分配9位来实现定点。 (其他位将用于符号)

在乘法中,我首先扩展了每个值的位长,以避免溢出。乘法后,左移将发生乘法输出的相同小数部分。

此外,我为输出添加了饱和度,以避免任何溢出(如果发生溢出,则输出将保持其最大绝对值,而与符号无关)

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

#define fractional_bits 22
#define fixed_type_bits 32

typedef int32_t fixed_type;
typedef int64_t expand_type;

fixed_type float_to_fixed(float inp)
{
    return (fixed_type)(inp * (1 << fractional_bits));
}

float fixed_to_float(fixed_type inp)
{
    return ((float)inp) / (1 << fractional_bits);
}

fixed_type fixed_mult(fixed_type inp_1, fixed_type inp_2)
{
    return (fixed_type)(((expand_type)inp_1 * (expand_type)inp_2) >> fractional_bits);
}

fixed_type fixed_add(fixed_type inp_1, fixed_type inp_2)
{
    fixed_type inp_1_sign = inp_1 >> (fixed_type_bits - 1);
    fixed_type inp_2_sign = inp_2 >> (fixed_type_bits - 1);
    fixed_type add = inp_1 + inp_2;
    fixed_type add_sign = add >> (fixed_type_bits - 1);

    if (inp_1_sign != inp_2_sign)
    {
        return add;
    }
    else if (add_sign == inp_1_sign)
    {
        return add;
    }
    else if (add_sign == -1)
    {
        return ((1 << (fixed_type_bits - 2)) - 1 + (1 << (fixed_type_bits - 2)));
    }
    else if (add_sign == 1)
    {
        return (1 << (fixed_type_bits - 1));
    }
}