将浮点数转换为4 uint8_t

时间:2014-08-19 14:48:35

标签: c++ casting type-conversion floating-point-conversion uint8t

我需要通过CAN协议发送 float变量。为此,必须使用 4 uint8_t个变量来剪切32位浮点数。

我完全不知道该怎么做。我首先考虑将float转换为int但我在互联网上找到的一些答案,使用 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
...

5 个答案:

答案 0 :(得分:7)

通常通过将float转换为uint8_t数组来执行此操作。

在C中你可以这样做:

uint8_t *array;
array = (unit8_t*)(&f);
C ++中的

使用reinterpret_cast

uint8_t *array;
array = reinterpret_cast<uint8_t*>(&f);

然后数组[0],...,数组[3]是你的字节。

答案 1 :(得分:2)

首先,您应该注意标准对float没有特定的尺寸限制。在某些可想象的架构上,float可能不适合四个字节(尽管我不知道任何架构)。在尝试任何事情之前,你至少应该(static_)声明它适合。

然后我认为最简单的方法是断言CHAR_BIT8,并使用unsigned char*reinterpret_cast合法别名:

static_assert(sizeof(float) == 4);
float f = 0; // whatever value
unsigned char* float_as_char = reinterpret_cast<unsigned char*>(&f);

这完全忽略了endian问题,所以也许你真正想要的是复制字节以便你可以解决这个问题:

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.

答案 2 :(得分:1)

这是一种联合方法,它为整数部分而不是一个数组提供单独的名称:

union {
    float f;
    struct {
        uint8_t ut1, ut2, ut3, ut4;
    } bytes;
} value;
value.f = 1.f;
uint8_t first = value.bytes.ut1;

我最初担心union使用{{1}}根据标准并不严格合法:C++ Undefined behaviour with unions但ComicSansMS对rashmatash答案的评论是有说服力的。

答案 3 :(得分:1)

您可以执行此非法操作:

float f = someFloatValue;
uint8_t* i = reinterpret_cast<uint8_t*>(&f);

尽管这在大多数情况下都有效,但c ++标准并不支持它,编译器可能会生成具有未定义行为的代码。

另一种解决方案是使用工会:

union{
    float f;
    uint8_t i[4];
}
f = someFloatValue;
// now i's contain the bit pattern of f

目前还不清楚所有编译器是否会产生一致的结果,但它似乎比第一次编程更安全。

您还可以将f的值打包为32位整数。然而,这可能会导致精确度下降,但取决于您希望保留f的准确程度,这将是最佳解决方案。

答案 4 :(得分:0)

这是基于此 paper

的基于表格的实现

它将一个 32 位浮点数转换为一个 16 位浮点数,并将其存储在一个无符号的 16 位值中。这两个 LUT 位于静态内存中,因此可以创建这些数组,并且它可以处理所有极端情况并且速度很快。(详情请参阅论文)

using flt32 = float;
class flt16 {
public: // clucnky but functional and fast
flt16(flt32 in) { 
    ftoi_t fi{ in };
    half = basetable[(fi.i >> 23) & 0x1ff] + ((fi.i & 0x007fffff) >> shifttable[(fi.i >> 23) & 0x1ff]);
}

union ftoi_t{
    flt32 f;
    uint32 i;
};

uint16 half;

static constexpr uint16 basetable[512] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192,
    9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 17408, 18432, 19456, 20480, 21504, 22528,
    23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
    31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 32768, 32768, 32768, 32768, 32768,
    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
    32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
    32769, 32770, 32772, 32776, 32784, 32800, 32832, 32896, 33024, 33280, 33792, 34816, 35840, 36864,
    37888, 38912, 39936, 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128, 49152, 50176, 51200,
    52224, 53248, 54272, 55296, 56320, 57344, 58368, 59392, 60416, 61440, 62464, 63488, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
    64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512
};

static constexpr uint8 shifttable[512] = {
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 
    14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 
    18, 17, 16, 15, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 
    13, 13, 13, 13, 13, 13, 13, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
    24, 24, 24, 24, 24, 24, 24, 13
};

};