将一个32位浮点数转换为两个16位uint数,然后再转换回该32位浮点数

thu*_*ium 1 c

我正在研究从一个平台到另一个平台的32位浮点数.那么它只允许将16位unsinged int成员传递给transfter寄存器.我想我可以将32位浮点分成两个16位然后再转换到另一侧的32位.

(我使用的是C语言)

喜欢:

float A = 3.14
uint16_t B = A & 0xffff;
uint16_t C = A & 0xffff0000;

float D = C<<16 & B;
Run Code Online (Sandbox Code Playgroud)

显然这是不正确的,因为浮动数据在分配时将转换为unsigned int.那我该怎么办呢?做一些类似的事情会有一些相当成熟的方法

谢谢

Pau*_*l R 5

您可以使用联合,例如:

typedef union {
    float f;
    uint16_t a[2];
} U;

U u;

u.f = 3.14f;

printf("%g -> %#x %#x\n", u.f, u.a[0], u.a[1]);
Run Code Online (Sandbox Code Playgroud)

LIVE DEMO

注意:严格来说这是未定义的行为,但它是一种广泛使用的技术,它不太可能失败.或者,您可以采用更安全但可能效率稍低的方法,并使用memcpy,如下所示:

float f = 3.14f;
uint16_t a[2];
memcpy(a, &f, sizeof(a));
printf("%g -> %#x %#x\n", f, a[0], a[1]);
Run Code Online (Sandbox Code Playgroud)

LIVE DEMO

  • 也许最好使用中间uint32_t并手动屏蔽/合并16位片段以帮助解释字节顺序差异.毕竟,这个数字正在"平台"之间转移. (2认同)
  • 未定义的行为只是一个意外.它是在C90中实现定义的,在C99中明确未定义,但在TC3中已修复(参见[DR 283](http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_283.htm) )和C11.这里的标准有点模糊(类似的缺陷报告[DR 236](http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm)中有一些链接到委员会的讨论,为什么很难明确地定义它,但意图非常清楚,编制者总是支持它. (2认同)