将32位转换为浮点值

ans*_*shu 5 c linux embedded

我正在研究DSP处理器,以便在Linux系统上使用C实现BFSK跳频机制.在程序的接收器部分,我得到一组样本的输入,我使用Goertzel算法解调,以确定接收的位是0还是1.

现在,我能够分别检测这些位.但我必须以float数组的形式返回数据进行处理.所以,我需要打包接收到的每一组32位来形成一个浮点值.对,我做的事情如下:

uint32_t i,j,curBit,curBlk;
unint32_t *outData; //this is intiallized to address of some pre-defined location in DSP memory
float *output;
for(i=0; i<num_os_bits; i++) //Loop for number of data bits
{ 

//Demodulate the data and set curBit=0x0000 or 0x8000

curBlk=curBlk>>1;
curBlk=curBlk|curBit;

bitsCounter+=1;
    if(i!=0 && (bitsCounter%32)==0) //32-bits processed, save the data in array
    {
        *(outData+j)=curBlk;
        j+=1;
        curBlk=0;
    }
}

output=(float *)outData;
Run Code Online (Sandbox Code Playgroud)

现在,output数组的值只是outData小数点后0 的数组值.例如:如果output[i]=12345`outData [i] = 12345.0000'.

但在测试程序时,我使用float数组生成位的样本测试数据 float data[] ={123.12456,45.789,297.0956};

因此在解调之后我期望浮点数组output具有与data数组相同的值.是否有其他方法可以将32位数据转换为浮点数.我应该将收到的位存储到char数组中,然后将其转换为float.

Ren*_*řík 6

不确定我是否明白你的意思 - 你顺序获得了一些比特,如果你有32位,你想从它们那里得到一个浮点数?

关于什么:

union conv32
{
    uint32_t u32; // here_write_bits
    float    f32; // here_read_float
};
Run Code Online (Sandbox Code Playgroud)

这可以像这样在线使用:

float f = ((union conv32){.u32 = my_uint}).f32;
Run Code Online (Sandbox Code Playgroud)

或者使用辅助变量:

union conv32 x = {.u32 = my_uint};
float f = x.f32;
Run Code Online (Sandbox Code Playgroud)


Cli*_*ord 5

您需要逐字复制位模式而不调用任何隐式转换。最简单的方法是获取数据的地址,并在取消引用它之前将其重新解释为指向中间“载体”类型的指针。

考虑一下:

float source_float = 1234.5678f ;
uint32_t transport_bits = *((uint32_t*)&source_float);
float destination_float = *((float*)&transport_bits);
Run Code Online (Sandbox Code Playgroud)

中的中间结果transport_bits取决于目标,在我对 x86 的测试中,它是 0x449a522b,这是该平台上单精度浮点数的位表示(浮点表示和字节序依赖)。

无论哪种方式,结果destination_float都与source_float通过uint32_t transport_bits.

然而,这确实要求发起者的浮点表示与接收者的浮点表示相同,这可能不是给定的。这有点不可移植,您的代码不起作用的事实表明,发送方和接收方之间的表示方式确实不同。不仅 FP 表示必须相同,而且字节顺序也必须相同。如果它们不同,您的代码可能必须对位进行重新排序之一或两者,并通过提取指数和尾数来计算等效浮点数。因此,您需要确保位的传输顺序与重新组装它们的顺序相同。有很多机会犯这个错误。

  • 不幸的是,这会调用具有严格别名规则的未定义行为。只有两种符合标准的方法可以做到这一点:1. 填充 `char` 数组并将其指针转换为 `float*`(严格别名规则对 `char` 类型有明确的例外),或 2. 使用 `memcpy ()`。 (2认同)