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

  • 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

  • The Keil C compiler is not the smartest in the world when it comes to optimization. In some situations it will never match the performance of direct assembler coding, whatever ways of doing the same thing in C you try.

  • 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.