我有一个需要通过CAN协议发送的**float
变量**。为此,必须将此32位浮点数切割为4个uint8_t
变量。
我完全不知道怎么做。我首先想到的是将浮点数转换为整型,但我在网上找到的一些答案,其中使用 cast 或 union 似乎不起作用。
这里有一个简单的例子,我正在尝试做什么:
float f;
uint8_t ut1,ut2,ut3,ut4;
//8 first bits of f into ut1
//8 second bits of f in ut2
...
// Then I can send the uint8_t through CAN
...
4条答案
按热度按时间slmsl1lt1#
通常通过转换浮点数
to an array of
uint8_t '来实现。在C语言中,可以这样做:
在C++中,最好使用
reinterpret_cast
:那么
array[0]
,...,array[3]
就是你的字节。dgtucam12#
首先,您应该注意到,标准对
float
没有具体的大小限制。在一些可以想象的架构上,float
可能无法容纳4个字节(尽管我不知道有任何架构)。在尝试任何操作之前,您至少应该(static_)Assert它将适合。那么我认为最简单的方法是Assert
CHAR_BIT
是8
,并使用法律的别名unsigned char*
和reinterpret_cast
:这完全忽略了字节序问题,所以也许你真正想要的是制作一个字节的副本,这样你就可以解决这个问题了:
o2rvlv0m3#
您可以执行以下非法操作:
虽然这在大多数情况下都有效,但它不受c++标准的支持,编译器可能会生成行为未定义的代码。
另一个解决方案是使用联合:
不清楚是否所有编译器都产生一致的结果,但它似乎比第一种方法更安全。
你也可以把
f
的值打包成一个32位的整数,但是这可能会导致丢失一些精度,但是这取决于你想保持f
的精度,这是最好的解决方案。aelbi1ox4#
下面是一个基于paper的基于表的实现
它将一个32位浮点数转换为一个16位浮点数,并将其存储为一个无符号的16位值。两个LUT位于静态内存中,因此可以创建这些LUT的数组,它可以处理所有的极端情况,沿着速度很快。(详细信息请参阅文章)
};