我需要从串口读取数据,它们是小端的,但我需要实现平台无关性,所以我必须处理double
的字节序。我没有找到任何地方可以解决这个问题,所以我写了自己的函数。但我不确定它是否正确。(而且我也没有一台大端机器来测试它)。
这个函数能正常工作吗?或者有更好的方法吗?我无法找到。
double get_double(uint8_t * buff){
double value;
memcpy(&value,buff,sizeof(double));
uint64_t tmp;
tmp = le64toh(*(uint64_t*)&value);
value = *(double*) &tmp;
return value;
}
我计算使用的double
长度为8字节,所以请不要担心这个问题。我知道可能会出现问题。
编辑:在得到建议后,我使用了union,代码如下:
union double_int{
double d;
uint64_t i;
};
double get_double(uint8_t * buff){
union double_int value;
memcpy(&value,buff,sizeof(double));
value.i = le64toh(value.i);
return value.d;
}
更好了吗?(虽然我没有看出很大的区别)
编辑2:第三次尝试,你现在觉得怎么样?
double get_double(uint8_t * buff){
double value;
uint64_t tmp;
memcpy(&tmp,buff,sizeof(double));
tmp = le64toh(tmp);
memcpy(&value,&tmp,sizeof(double));
return value;
}
编辑3:我使用gcc -std=gnu99 -lpthread -Wall -pedantic
编译它。
编辑4:在下一个建议后,我添加了一个检查字节序的条件。老实说,我现在不知道自己在做什么(难道不应该有像__DOUBLE_WORD_ORDER__
这样的东西吗?)
double get_double(uint8_t * buff){
double value;
if (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__){
uint64_t tmp;
memcpy(&tmp,buff,sizeof(double));
tmp = le64toh(tmp);
memcpy(&value,&tmp,sizeof(double));
}
else {
memcpy(&value,buff,sizeof(double));
}
return value;
}
union
关键字对于避免memcpy(&tmp,buff,sizeof(double));
步骤非常有用,但不能解决“字节序”问题。 - chux - Reinstate Monica