-5

I have three integers, one integer contains data of 7 bits, another integer contains data of 4 bits and the third integer contains data of 5 bits.

I want to concatenate all the three integers into one 16-bit integer side by side without changing the value of each of the integers.

Example:

int a = 1; //7 bit data (uint8)
int b = 2; //4 bit data (uint8)
int c = 3; //5bit data (uint8)

where, 0< a <100 , 0< b < 13, 0< c <32 The result should be as follows:

result = 123;

Example 2:

int a = 99; //7 bit data (uint8)
int b = 12; //4 bit data (uint8)
int c = 31; //5bit data (uint8)

result = 991231; //expected

How can this be achieved using bit wise operators?

sre
  • 67
  • 9
  • 1
    What have you *tried*? Have you experimented with the bitwise operators before? Have you tried using the bitwise shift and bitwise or operators? I suggest you do that, experimenting with shifting and bitwise oring some values and see what you get. – Some programmer dude Jun 28 '17 at 11:40
  • 1
    Try with *`unsigned`* first, it is simpler. – Weather Vane Jun 28 '17 at 11:41
  • 2
    Question makes no sense: `991231` does not fit into 16 bits. – user694733 Jun 28 '17 at 11:47
  • @ShreedharHegde try `a*10000 + b*100 + c` you're putting decimal digits into the result so bitwise operations are not help here – phuclv Jun 28 '17 at 11:50
  • Possible duplicate of [Converting Bit Field to int](https://stackoverflow.com/questions/2468708/converting-bit-field-to-int) – Ctx Jun 28 '17 at 11:51
  • @ShreedharHegde see answer below. – Jabberwocky Jun 28 '17 at 11:51
  • `((((0u|a) << 7) | b) << 4) | c` is a start for bit-wise packing, yet `991231` is > 16-bit. – chux - Reinstate Monica Jun 28 '17 at 11:51
  • @ShreedharHegde your question only makes sense if you remove the `//16-bit integer (uint16)` comment from the code snippet and the text "_16-bit_" from the question text. – Jabberwocky Jun 28 '17 at 11:53
  • 1
    Definitlely not a duplicate of https://stackoverflow.com/questions/2468708/converting-bit-field-to-int – Jabberwocky Jun 28 '17 at 11:54
  • @MichaelWalz Since this is an elegant method of achieving what the OP wants, I propose that. What do you try to achieve with your noise? – Ctx Jun 28 '17 at 11:56
  • @Ctx which method do you mean? I don't see how [Converting Bit Field to int](https://stackoverflow.com/questions/2468708/converting-bit-field-to-int) is related to the question. Correct me if I'm Wrong. – Jabberwocky Jun 28 '17 at 12:02
  • @MichaelWalz The first answer shows up a good way to achieve, what the OP wants. – Ctx Jun 28 '17 at 12:03
  • 1
    @Ctx: The answer shows some bad way to type-pun a bitfield struct to an integer, yes. But it is implementation defined and possibly more complicated than shifts/masks. Bitfields have no defined layout. – too honest for this site Jun 28 '17 at 12:06
  • @Olaf "More complicated" depends on the view. I personally find the code quite self-explaining when using a structure with bitfields compared with a bitshift-or-method. YMMV. – Ctx Jun 28 '17 at 12:09
  • @Ctx This absolutely doesn't work for what the OP wants: Démonstration: http://ideone.com/GP2RG4 – Jabberwocky Jun 28 '17 at 12:10
  • @Ctx: It is not less source code, but possibly more machine code. A good compiler will turn the shifts/masks into bitfield instructions if the arch supports them and a common pattern is used. – too honest for this site Jun 28 '17 at 12:10
  • @MichaelWalz Hm, yes, now reading the "examples" I see that the OP wants something different, the comments mislead me. – Ctx Jun 28 '17 at 12:13
  • @Olaf If you want a competition for the smallest source code, I'd suggest you go to codegolf.stackexchange.com . – Ctx Jun 28 '17 at 12:14
  • @ctx Good you missed the point! I'd recommed to read the accepted answer with the standard nearby. – too honest for this site Jun 28 '17 at 12:37

1 Answers1

1

What about something like the following? You modify it to works for three integers and for the size you want.

unsigned concatenate(unsigned x, unsigned y) {
    unsigned pow = 10;
    while(y >= pow)
        pow *= 10;
    return x * pow + y;        
}
 int main(){

    int a=1,b=2,c=3;
    printf("%d\n", concatenate(concatenate(a,b),c));
 }

credit to: How to concatenate two integers in C

If you feel brave and you are using c++ you can extend it in order to work with a variable number of arguments.

template <typename T>
inline T concatenate(T N){
     return N;
}
template <typename T,typename...NS>
T concatenate(const T N, NS&&... ns){
    const T rest = concatenate(std::forward<NS>(ns)...);
    unsigned pow = 10;
    while(rest >= pow)
        pow *= 10;
    return N * pow + rest;      
}

int main()
{
    int a=1,b=2,c=3;
    printf("%d\n", concatenate(a,b,c,987,a));
}
Davide Spataro
  • 7,319
  • 1
  • 24
  • 36
  • 1
    Hmm, looks like infinite loop with `concatenate(..., -1u)` - good start hough. – chux - Reinstate Monica Jun 28 '17 at 11:54
  • @chux it works for the number ranges mentioned in the question. – Jabberwocky Jun 28 '17 at 11:57
  • Yes, it dies when given `-1u` (after all it's a bit hard to squeeze something into a container that's already completely full =) ). Seems to be working for the range specified in the question (quite small numbers). Good observation though, I didn't think about this case. – Davide Spataro Jun 28 '17 at 12:00
  • That does not answer the question. And we are not a coding service. – too honest for this site Jun 28 '17 at 12:03
  • @Olaf while I was answering the question got edited. – Davide Spataro Jun 28 '17 at 12:05
  • @Olaf yes it does answer the question. The OP is talking about bitwise operators, but actually his examples are not related at all to bitwise operations. Correct me if I'm wrong. If you ignore all "bit" related stuff in the question, it makes sense. – Jabberwocky Jun 28 '17 at 12:16
  • @MichaelWalz the only thing not making sense is the result. It contradicts the rest on the text, indeed. It also makes the question unclear, hence it should not have been answered. – too honest for this site Jun 28 '17 at 12:40