Convert a float to 4 uint8_t
我有一个需要通过CAN协议发送的
我绝对不知道该怎么做。 我最初想到的是将float转换为int,但是我在互联网上找到的使用cast或union的一些答案似乎无效。
这是我尝试做的一个简单示例:
1 2 3 4 5 6 7 8 9 | 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 ... |
通常,您可以通过将浮点数强制转换为uint8_t数组来实现此目的。
在C中,您可以这样操作:
1 2 | uint8_t *array; array = (unit8_t*)(&f); |
在C ++中使用reinterpret_cast
1 2 | uint8_t *array; array = reinterpret_cast<uint8_t*>(&f); |
然后array [0],...,array [3]是您的字节。
首先,您应该注意,该标准没有对
然后,我认为最简单的方法是断言
1 2 3 | static_assert(sizeof(float) == 4); float f = 0; // whatever value unsigned char* float_as_char = reinterpret_cast<unsigned char*>(&f); |
但是,这完全忽略了字节序问题,因此也许您真正想要的是复制字节,以便您可以解决此问题:
1 2 3 4 5 | static_assert(sizeof(float) == 4); float f = 0; // whatever value uint8_t bytes[4]; std::memcpy(bytes, &f); // Fix up the order of the bytes in"bytes" now. |
您可以执行以下非法操作:
1 2 | float f = someFloatValue; uint8_t* i = reinterpret_cast<uint8_t*>(&f); |
尽管这在大多数情况下都有效,但是c ++标准不支持它,并且编译器可能会生成具有未定义行为的代码。
另一个解决方案是使用联合:
1 2 3 4 5 6 | union{ float f; uint8_t i[4]; } f = someFloatValue; // now i's contain the bit pattern of f |
尚不清楚是否所有编译器都能产生一致的结果,但似乎比第一个方法更安全。
您还可以将
这是一种联合方法,为整数部分(而不是一个数组)提供单独的名称:
1 2 3 4 5 6 7 8 | union { float f; struct { uint8_t ut1, ut2, ut3, ut4; } bytes; } value; value.f = 1.f; uint8_t first = value.bytes.ut1; |
最初,我担心根据标准使用