This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

compose a Long of two Ints

Hello Forum,
I want to compose two int variables, which contains the LSW and MSW, respective, into one unsigned long variable.
The following code does the right thing:

int lo, hi;
unsigned long longvar;
longvar = (unsigned long) (unsigned int) hi << 16 | (unsigned long) (unsigned int) lo;
But the compiled code is rather complicated. Are there possiblities to do this more straightforward (beside the use of an union)?
Something like
longvar.msw = hi;
longvar.lsw = lo;
?
Thanks for all hints and tips - Peter

Parents
  • How about using a union. For example:

    struct int_st
      {
      unsigned int i1;
      unsigned int i2;
      };
    
    union long_u
      {
      unsigned long l1;
      struct int_st is1;
      };
    

    Then, in your program, you can use...

    union long_u xxx;
    unsigned int a1,a2;
    
    xxx.l1 = 0x12345678;
    
    a1 = xxx.is1.i1;
    a2 = xxx.is1.i2;
    

    Jon

Reply
  • How about using a union. For example:

    struct int_st
      {
      unsigned int i1;
      unsigned int i2;
      };
    
    union long_u
      {
      unsigned long l1;
      struct int_st is1;
      };
    

    Then, in your program, you can use...

    union long_u xxx;
    unsigned int a1,a2;
    
    xxx.l1 = 0x12345678;
    
    a1 = xxx.is1.i1;
    a2 = xxx.is1.i2;
    

    Jon

Children
  • Peter Muthesius wondered:
    Are there possiblities to do this more straightforward (beside the use of an union)?

    Jon Ward replied:
    How about using a union.

    Peter:
    Thanks

    So why did you initially want to avoid Unions?

    Note that the solution with Unions is implementation-dependant - it depends on the byte & word ordering & alignment of the target & compiler. But it'll be the quickest, as it doesn't involve actually moving any data.

    I s'pose you could achieve the same effect by casting an abstract pointer - if you really want to avoid using a Union (may be less efficient than a Union, depending on how smart the compiler is with its pointers)

    The shift-and-mask solution, on the other hand, is portable - but slower as it does actually move the data about.

  • Hello,
    sorry - I've said "thanks" somewhere in the thread to say "thanks" to all posters, regardless I used they suggestions or not.
    The reason why I wont use unions is the already meanted little/big endian problem. I use a solution that depends on the ordering - that's ok because the ordering doesn't change.
    In general, I expect the ordering wont change at runtime. Therefore, to get the right solution, the ordering must be known at compiletime.
    The reason why I'd asked here is that I supposed there is a solution that uses the same .c input, but gets different output, based on the compilers knowledge on byte/word ordering; without forcing me to know about the ordering.
    As a conclusion, I'm still using the solution that depends on the ordering...

    - Peter

    Sorry if there is any strange language, but I'm not a native speaker.