# Concatenate three 16-bit integers in one 64-bit integer with C++

I am looking for an elegant alternative of the following code where wordXX contains always 16 bits:

uint64_t wordHi = 0xaa; // I would like u_int16_t over u_int64_t here
uint64_t wordMi = 0xbb; // because it represents the real data better
uint64_t wordLo = 0xcc;

uint64_t largeword = (wordHi << 32) + (wordMi << 16) + (wordLo << 0);


To me this (very simplified) code looks a bit dirty, because reader gets confused about the real size of the wordXX data.

I could store wordHi to largeword and then shift largeword and add wordMi and so on, but this would make the code worse and probably needs more CPU cycles.

Edit: changed u_int64_t to uint64_t in the example as suggested in the comments.

• Please either post your real code or remove the "very simplified" disclaimer. – 200_success Mar 2 '16 at 22:34
• The performance concerns of a handful of bit operations are almost certainly going to be negligible. Even if this is inside the tightest loop you can imagine, I highly doubt that you would see much of a performance hit over that, and I strongly doubt you could find a more readable and efficient method of doing that. – Dannnno Mar 2 '16 at 22:34
• @200_success with simplified I want to express that the 16-bit integers are of course not constant values. So largeword = 0xaabbcc; would not help me a lot. – Jonas Stein Mar 2 '16 at 22:41
• @Dannnno to me it looks strange to convert all 16-bit values to 64-bit, just to be able to shift them later. OK I could store wordMi to 32-bit and wordLo to 16-bit. But that makes it not much better... – Jonas Stein Mar 2 '16 at 22:45
• Why are you using u_int64_t instead of the standard uint64_t? Why aren't you using u_int16_t for the words? – 200_success Mar 2 '16 at 22:46

### Using uint16_t not a problem?

Your comment says you want to use uint16_t, so why don't you do that? It would make the code look like this:

uint16_t wordHi = 0xaa;
uint16_t wordMi = 0xbb;
uint16_t wordLo = 0xcc;

uint64_t largeword = ((uint64_t) wordHi << 32) + ((uint64_t) wordMi << 16) + wordLo;


Use a struct and a union to do what you want. Note that this implementation is verbose and can be combined into a single declaration. Also depending on your system architecture, you may need to pack the struct or declare the members in a different order.

typedef struct
{
uint16_t Low;
uint16_t Mid;
uint16_t Hi;
uint16_t Spare;
} Word64_t;

typedef union
{
uint64_t Int64Val;
Word64_t WordVal;
} Splitter_t;

Splitter_t splitter;
splitter.WordVal.Low = 0xaa;
splitter.WordVal.Mid = 0xbb;
splitter.WordVal.Hi = 0xcc;

printf("%x", splitter.Int64Val);  //should print 0xaabbcc

• I think you would run into endianness issues with this solution. – JS1 Mar 3 '16 at 1:39
• @JS1 That may be. It depends on the architecture, as I said. I do this all the time in embdeded. – Zack Mar 3 '16 at 3:15
• If you can check the endianness of your architecture in a #define, you could define the order of elements in the struct differently based on the value of the #define. – user1118321 Mar 3 '16 at 3:34