user5613933
user5613933

Reputation:

Concatenating bits

I have have to concatenate the bits of the int. For example:

unsigned char byte1 = 0x0F;   // 00001111
unsigned char byte2 = 0xCC;   // 11001100
unsigned char byte3 = 0x55;   // 01010101
unsigned char byte4 = 0x04;   // 00000100

After concatenation the result should be:

00000100010101011100110000001111 

I tried doing smth like:

unsigned int temp = 0;
temp = temp | byte1; //the result should be 00001111 for now

temp = temp >> 8;
byte2 = byte2 << 8;
temp = temp | byte2; //the result should be 1100110000001111 for now

temp = temp >> 8;
byte3 = byte3 << 8;
temp = temp | byte3; //the result should be 010101011100110000001111 for now

temp = temp >> 8;
byte4 = byte4 << 8;
temp = temp | byte4; //the result should be 00000100010101011100110000001111

But when I print the temp, it shows 0:

printf("%d", temp) //===> gives 0

Upvotes: 2

Views: 2351

Answers (3)

nobody
nobody

Reputation: 4264

It seems you misunderstand the layout of your data. The temp = temp >> 8 always shifts out what you just added:

uint32_t temp = 0; // 00000000 00000000 00000000 00000000
temp |= byte1;     // 00000000 00000000 00000000 00001111
temp = temp >> 8;  // 00000000 00000000 00000000 00000000
// and so on...

The bytes, when combined with larger numbers, are zero-extended on the left (not on the right), so shifting them to the right will remove them again.

There's two obvious ways of writing this:

The first is to shift the bytes left to the right place before or-ing them into the result:

uint32_t temp = 0;     // 00000000 00000000 00000000 00000000
temp |= byte1;         // 00000000 00000000 00000000 00001111
temp |= (byte2 <<  8); // 00000000 00000000 11001100 00001111
temp |= (byte3 << 16); // 00000000 01010101 11001100 00001111
temp |= (byte4 << 24); // 00000100 01010101 11001100 00001111

The other is to shift temp to the left (not to the right) and or-ing the bytes into it in their "normal" (un-shifted) place:

uint32_t temp = 0; // 00000000 00000000 00000000 00000000
temp |= byte4;     // 00000000 00000000 00000000 00000100
temp = temp << 8;  // 00000000 00000000 00000100 00000000
temp |= byte3;     // 00000000 00000000 00000100 01010101
temp = temp << 8;  // 00000000 00000100 01010101 00000000
temp |= byte2;     // 00000000 00000100 01010101 11001100
temp = temp << 8;  // 00000100 01010101 11001100 00000000
temp |= byte1;     // 00000100 01010101 11001100 00001111

Both can be written concisely, as in:

uint32_t temp = (byte4 << 24) | (byte3 << 16) | (byte2 << 8) | byte1;

or

uint32_t temp = ((byte4 << 8 | byte3) << 8 | byte2) << 8 | byte1;

Upvotes: 1

Adam
Adam

Reputation: 17339

unsigned int byte1 = 0x0F; // 00001111; //byte1
unsigned int byte2 = 0xCC; // 11001100; //byte2
unsigned int byte3 = 0x55; // 01010101; //byte3
unsigned int byte4 = 0x04; // 00000100; //byte4

unsigned int temp = (byte1) | (byte2 << 8) | (byte3 << 16) | (byte4 << 24);
printf("%u", temp);

prints 72731663 which is 00000100010101011100110000001111.


If you want to keep your inputs as unsigned char, then this has the same result:

unsigned char byte1 = 0x0F; // 00001111; //byte1
unsigned char byte2 = 0xCC; // 11001100; //byte2
unsigned char byte3 = 0x55; // 01010101; //byte3
unsigned char byte4 = 0x04; // 00000100; //byte4

unsigned int temp = byte4;
temp <<= 8;
temp |= byte3;
temp <<= 8;
temp |= byte2;
temp <<= 8;
temp |= byte1;
printf("%u", temp);

Upvotes: 3

t-town
t-town

Reputation: 56

Actually it seems to me the

temp = temp >> 8;

bitshifts away your entire temp value.

Upvotes: 3

Related Questions