Hi,
Need help on the union usage.
typedef union
{
BYTE c[4];
UINT32 u32;
} CNY_U32;
UINT32 ReadUIN32 (FILE *stream)
{
CNY_U32 cny;
cny.c[3] = (BYTE) fgetc(stream); // 0x08 is read
cny.c[2] = (BYTE) fgetc(stream); // 0x00 is read
cny.c[1] = (BYTE) fgetc(stream); // 0x00 is read
cny.c[0] = (BYTE) fgetc(stream); // 0x00 is read
return (cny.u32);
}
I want it to be returned as 0x000008, that why i input the index 3 first, but the return value of ReadUIN32 funciton is always 0x800000.
Please help, how I can return the value as 0x000008.
Thank you.
9 replies to this topic
#1
Posted 17 August 2011 - 10:24 PM
|
|
|
#2
Posted 18 August 2011 - 07:18 AM
The behavior is going to be implementation defined. Are you on a big-endian or little-endian system?
Have you tried reversing the order you load the bytes?
Have you tried reversing the order you load the bytes?
#3
Posted 22 August 2011 - 05:08 AM
This will do it for you me thinks...
typedef union
{
BYTE c[4];
UINT32 u32;
} CNY_U32;
UINT32 ReadUIN32 (FILE *stream)
{
CNY_U32 cny;
BYTE *p = &cny.c[3];
*p-- = (BYTE) fgetc(stream); // 0x08 is read
*p-- = (BYTE) fgetc(stream); // 0x00 is read
*p-- = (BYTE) fgetc(stream); // 0x00 is read
*p = (BYTE) fgetc(stream); // 0x00 is read
return (cny.u32);
}
#4
Posted 23 August 2011 - 04:18 AM
It's probably all about endianess, as WingedPanther said. The Gixxerman code may be elegant, but it will hardly solve the problem.
(ARM and Intel are normally little endian = This behavior. Coldfire etc big endian = would work as you expect)
(ARM and Intel are normally little endian = This behavior. Coldfire etc big endian = would work as you expect)
#5
Posted 23 August 2011 - 05:40 AM
Jokke said:
It's probably all about endianess, as WingedPanther said. The Gixxerman code may be elegant, but it will hardly solve the problem.
Thanks for the "elegant" though ;-).
#6
Posted 23 August 2011 - 05:48 AM
Please explain??
#7
Posted 23 August 2011 - 06:01 AM
It is logical to assume, is it not, that if the computer he is running the code on is getting the data from the input stream in a particular order (endian), it will always get it in that order. So reversing the bytes before storing will always work, providing he continues to run the code on the same computer. There is no such guarantee if he runs in on another computer. I assumed that the user just wanted it to work on the computer in question. Nowhere did he specify that it was needed the code to be portable. There are techniques to asertain the endianess of the computer at runtime and the byte reversal could be dependant of the result of this test. Thus it would work forever on any endian machine. However, this would complicate the code unneccessarily, given what (I think) he is after. IMHO.
#8
Posted 23 August 2011 - 06:13 AM
But your code must return exactly the same result as did ihatessb's! You put the first byte in "cny.c[3]", the second in "cny.c[2]" etc.
#9
Posted 23 August 2011 - 06:41 AM
Jokke said:
But your code must return exactly the same result as did ihatessb's! You put the first byte in "cny.c[3]", the second in "cny.c[2]" etc.
OK, is this any better?
typedef union
{
BYTE c[4];
UINT32 u32;
} CNY_U32;
UINT32 ReadUIN32 (FILE *stream)
{
CNY_U32 cny;
BYTE *p = &cny.c[0];
*p++ = (BYTE) fgetc(stream); // 0x08 is read
*p++ = (BYTE) fgetc(stream); // 0x00 is read
*p++ = (BYTE) fgetc(stream); // 0x00 is read
*p = (BYTE) fgetc(stream); // 0x00 is read
return (cny.u32);
}
#10
Posted 23 August 2011 - 06:49 AM
That's right, now I get it! Thanks.
So to ihatessb:
Regardless of endianess this should work (not very elegant though ;-) ):
So to ihatessb:
Regardless of endianess this should work (not very elegant though ;-) ):
UINT32 ReadUIN32 (FILE *stream)
{
UINT32 res = 0;
BYTE i;
for(i = 0; i < 4; ++i) {
res |= (UINT32)fgetc(stream) << (8 * i);
}
return (res);
}
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account

Back to top









