Jump to content

Using union to return UINT32 (URGENT!)

- - - - -

  • Please log in to reply
9 replies to this topic

#1
ihatessb

ihatessb

    Newbie

  • Members
  • Pip
  • 1 posts
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.

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
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?
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
Gixxerman

Gixxerman

    Newbie

  • Members
  • Pip
  • 6 posts
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
Jokke

Jokke

    Newbie

  • Members
  • Pip
  • 4 posts
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)

#5
Gixxerman

Gixxerman

    Newbie

  • Members
  • Pip
  • 6 posts

Jokke said:

It's probably all about endianess, as WingedPanther said. The Gixxerman code may be elegant, but it will hardly solve the problem.
It will solve the problem in his particular case. Granted, it might not on all systems due to endianess, but that is not what was required.
Thanks for the "elegant" though ;-).

#6
Jokke

Jokke

    Newbie

  • Members
  • Pip
  • 4 posts
Please explain??

#7
Gixxerman

Gixxerman

    Newbie

  • Members
  • Pip
  • 6 posts
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
Jokke

Jokke

    Newbie

  • Members
  • Pip
  • 4 posts
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
Gixxerman

Gixxerman

    Newbie

  • Members
  • Pip
  • 6 posts

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.
Oh yeah. I didn't spot that. I had wrongly assumed that he was stroring them 0->3.
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
Jokke

Jokke

    Newbie

  • Members
  • Pip
  • 4 posts
That's right, now I get it! Thanks.

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