Мне нужно прочитать данные из последовательного порта. Они написаны с прямым порядком байтов, но мне нужно сделать это независимым от платформы, поэтому я должен учитывать порядок следования байтов 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;
}
p.s. Я считаю с double
8 байтами, так что не беспокойтесь об этом, пожалуйста. Я знаю, что могут быть проблемы с этим
РЕДАКТИРОВАТЬ: После предложения использовать союз, я сделал это:
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: попытка № 3, что вы думаете сейчас?
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;
}
Edit3: я компилирую его с помощью gcc -std=gnu99 -lpthread -Wall -pedantic
Edit4: после следующего предложения я добавил условие для проверки порядка байтов. Честно говоря, я понятия не имею, что я сейчас делаю (разве не должно быть что-то вроде __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;
}
uint64_t
могут отличаться отdouble
(маловероятно, да), и так далее. - person Antti Haapala   schedule 08.04.2016le64toh()
корректирует порядок байтов целого числа в зависимости от порядка байтов платформы и сети. Порядок следования байтовdouble
независим от целого числа.le64toh()
может быть полезно для выполнения замены байтов, но не для определения, требуется ли это дляdouble
. - person chux - Reinstate Monica   schedule 08.04.2016union
полезны для того, чтобы избежать шагаmemcpy(&tmp,buff,sizeof(double));
, но не шага с порядком байтов. - person chux - Reinstate Monica   schedule 08.04.2016