如何在 C 中处理一个浮点数以写入 4 个单独的字节?
How to address a float to write 4 individual bytes to it in C?
我有一个需要 32 位浮点数的函数,但是在某种模式下,它期望浮点数实际上只是 4 个 UINT8 组合在一起。
我编写的代码有效,但是我收到编译器警告 "illegal pointer" 警告,我想知道最 "correct" 的方法是什么?代码的可读性也非常重要,我认为我写的东西很容易阅读,尽管可能有一些方法可以用更少的行来写它。
UINT8 time[6];
FLOAT FSTtime = 0; //32bit float
UINT8 * FSTtimePointer;
//Get the current time as 6 bytes {secs,mins,hours,day,month,year}
returnSize = appP->DB_get_param_value(12, 0, 8, &time);
if (returnSize < 6) return;
(UINT8*)FSTtimePointer = &FSTtime; //Line 876
//Pack 4 bytes of time data into a "float"
FSTtimePointer [0] = time[3]; //Reverse month & day because americans are backwards
FSTtimePointer [1] = time[4];
FSTtimePointer [2] = time[2];
FSTtimePointer [3] = time[1];
appP->HIST_write_FST_log(SubMin_CFG.OFFSET, (UINT16)historyPointer, FSTtime);
HIST_write_FST_log 的原型是
void (*HIST_write_FST_log) (UINT8 hist_pt_index, UINT16 log_index, FLOAT value);
我收到的编译器警告是:
876: C1000 (W) Illegal pointer assignment
876: C1024 (W) First operand of "=" is not lvalue
如果有人感兴趣,我使用的编译器是用于日立处理器的 Renesas H8。
您可以使用修改代码如下
FSTtimePointer = (UINT8*) &FSTtime;
您确定这就是您要存储时间的方式吗?浮点数据类型的内部通常不按字节屏障对齐,日期通常是距纪元的秒数或毫秒数(通常为 UINT32
或 UINT64
),而不是浮点数点类型。您可能还需要考虑处理器中的 MSB 或 LSB 字节顺序。 (免责声明:我不知道 Hitachi 处理器如何处理字节顺序或浮点数据类型。)
如果您确定这就是您想要的方式,您应该能够使用 union
来寻址更大数据类型中的各个字节:
union converter_type
{
UNIT8 elements[4];
FLOAT whole;
} converter;
UINT8 time[6];
FLOAT FSTtime = 0; //32bit float
//Get the current time as 6 bytes {secs,mins,hours,day,month,year}
returnSize = appP->DB_get_param_value(12, 0, 8, &time);
if (returnSize < 6) return;
//Pack 4 bytes of time data into a "float"
converter.elements[0] = time[3]; //Reverse month & day because Americans are backwards
converter.elements[1] = time[4]; // (Yes, we are.)
converter.elements[2] = time[2]; // (But what about Canadians? They're "American", too! ;) )
converter.elements[3] = time[1];
FSTtime = converter.whole;
appP->HIST_write_FST_log(SubMin_CFG.OFFSET, (UINT16)historyPointer, FSTtime);
我有一个需要 32 位浮点数的函数,但是在某种模式下,它期望浮点数实际上只是 4 个 UINT8 组合在一起。
我编写的代码有效,但是我收到编译器警告 "illegal pointer" 警告,我想知道最 "correct" 的方法是什么?代码的可读性也非常重要,我认为我写的东西很容易阅读,尽管可能有一些方法可以用更少的行来写它。
UINT8 time[6];
FLOAT FSTtime = 0; //32bit float
UINT8 * FSTtimePointer;
//Get the current time as 6 bytes {secs,mins,hours,day,month,year}
returnSize = appP->DB_get_param_value(12, 0, 8, &time);
if (returnSize < 6) return;
(UINT8*)FSTtimePointer = &FSTtime; //Line 876
//Pack 4 bytes of time data into a "float"
FSTtimePointer [0] = time[3]; //Reverse month & day because americans are backwards
FSTtimePointer [1] = time[4];
FSTtimePointer [2] = time[2];
FSTtimePointer [3] = time[1];
appP->HIST_write_FST_log(SubMin_CFG.OFFSET, (UINT16)historyPointer, FSTtime);
HIST_write_FST_log 的原型是
void (*HIST_write_FST_log) (UINT8 hist_pt_index, UINT16 log_index, FLOAT value);
我收到的编译器警告是:
876: C1000 (W) Illegal pointer assignment
876: C1024 (W) First operand of "=" is not lvalue
如果有人感兴趣,我使用的编译器是用于日立处理器的 Renesas H8。
您可以使用修改代码如下
FSTtimePointer = (UINT8*) &FSTtime;
您确定这就是您要存储时间的方式吗?浮点数据类型的内部通常不按字节屏障对齐,日期通常是距纪元的秒数或毫秒数(通常为 UINT32
或 UINT64
),而不是浮点数点类型。您可能还需要考虑处理器中的 MSB 或 LSB 字节顺序。 (免责声明:我不知道 Hitachi 处理器如何处理字节顺序或浮点数据类型。)
如果您确定这就是您想要的方式,您应该能够使用 union
来寻址更大数据类型中的各个字节:
union converter_type
{
UNIT8 elements[4];
FLOAT whole;
} converter;
UINT8 time[6];
FLOAT FSTtime = 0; //32bit float
//Get the current time as 6 bytes {secs,mins,hours,day,month,year}
returnSize = appP->DB_get_param_value(12, 0, 8, &time);
if (returnSize < 6) return;
//Pack 4 bytes of time data into a "float"
converter.elements[0] = time[3]; //Reverse month & day because Americans are backwards
converter.elements[1] = time[4]; // (Yes, we are.)
converter.elements[2] = time[2]; // (But what about Canadians? They're "American", too! ;) )
converter.elements[3] = time[1];
FSTtime = converter.whole;
appP->HIST_write_FST_log(SubMin_CFG.OFFSET, (UINT16)historyPointer, FSTtime);