#c
Вопрос:
union sUnion {
unsigned long hex;
float var;
};
void Testcode(void)
{
char rdata[4] = { 0xd7, 0xa3, 0x40, 0xc1 }; // to DEC: -12.04
char ctemp[100];
union sUnion r;
r.hex = 0xc140a3d7; //<=== ??????
sprintf(ctemp, "hex = %x, float = %f", r.hex, r.var);
}
Я хочу поместить данные из rdata
в r.hex
переменную, чтобы получить результат -12.04
Комментарии:
1. Есть
sizeof (unsigned long)
ли 4 в вашей системе? (Также вам, вероятно, следует сделатьrdata
тип элемента sunsigned char
вместоchar
)2. в основном
r.hex = (rdata[3] << 24) | (rdata[2] << 16) | (rdata[1] << 8) | (rdata[0] << 0);
.3. Большое вам спасибо! Моя проблема решена!
4. @tehos помните, что такого рода решение, хотя легко и быстро, вызывает неопределенное поведение, и работает только, если: 1) платформа с прямым порядком байтов; 2)
float
является IEEE754 binary32 иsizeof(float) == 4
; 3)sizeof(unsigned long) == 4
; 4)CHAR_BIT == 8
(последняя может быть проигнорирован, если ваша программа будет работать только на Windows или POSIX-совместимых платформ). Таким образом, это не рекомендуется, особенно если вам приходится отправлять/получать данные по сети.
Ответ №1:
Если утверждение не выполняется, измените тип целого числа
_Static_assert (sizeof(unsigned long) == 4, "assert1");
#define INTLENGTH sizeof(unsigned long)
//endianess independent
unsigned long covert1(void *varr, int endianness)
{
unsigned char *arr = varr;
unsigned long resu<
#define MAXINDEX (INTLENGTH -1)
if(endianess)
result = (unsigned long)arr[0] ((unsigned long)arr[1] << 8) ((unsigned long)arr[2] << 16) ((unsigned long)arr[3] << 24);
else
result = (unsigned long)arr[MAXINDEX - 0] ((unsigned long)arr[MAXINDEX - 1] << 8) ((unsigned long)arr[MAXINDEX - 2] << 16) ((unsigned long)arr[MAXINDEX - 3] << 24);
return resu<
}
//arr has to have seme endianness as integers
unsigned long covert(void *arr)
{
unsigned long resu<
memcpy(amp;result, arr, sizeof(result));
return resu<
}