2015-11-28 6 views
2

Мне нужно объединить биты int. Например:Конкатенирующие биты

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

После конкатенации результат должен быть:

00000100010101011100110000001111 

Я пытался сделать что-л, как:

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 

Но когда я печатаю темп, он показывает 0:

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

@RNar, что вы имеете в виду? –

+0

Извините, я неправильно прочитал ваш код –

+0

Вы должны использовать 'unsigned int' (или' uint32_t' предпочтительно) и убедитесь, что ваши байты также являются символами unsigned char, а не plain или signed char. В противном случае вы столкнетесь с проблемами, потому что в C, '' 'и' << 'являются арифметическими операциями. –

ответ

3
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); 

печатает 72731663, который является 00000100010101011100110000001111.


Если вы хотите сохранить свои входы в unsigned char, то это имеет тот же результат:

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); 
+0

Не могли бы вы объяснить, как (byte2 << 8) или другие смены не заканчиваются с 0000000, @Adam? Например, byte2 составляет 11001100 и сдвигая его на 8, как получилось, что 11001100 << 8 не заканчивается 0000000, учитывая тот факт, что byte2 является unsigned char? Благодаря! –

+0

Я только 'byte2 << 8', если' byte2' является 'unsigned int'. В этом случае существует не менее 32 бит, и результат требует только 16. Я включил этот путь, потому что, когда я ответил, вы все еще не указали типы ваших байтовых переменных. Обратите внимание: если 'byte2' является' unsigned char' (вторая половина ответа), то я не делаю 'byte2 << 8', потому что, как вы говорите, это абсолютно нулевое значение. – Adam

3

На самом деле кажется t o me

temp = temp >> 8; 

сбрасывает всю вашу температуру.

+0

возможно, да, если это что-то близко к поразрядным операторам Java, OP должно «<< 8» текущее значение, а затем '|' оно со следующим – Aaron

1

Кажется, вы неправильно расположение данных. temp = temp >> 8 всегда сдвигает, что вы только что добавили:

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

байты, в сочетании с большим числом, равны нулю, распространяется на левом (не справа), так смещая их вправо удалит их снова ,

Там в два очевидных способа написания этого:

Первый сдвиг байтов влево на нужное место до или-ки их в результат:

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 

Другой перекладывать temp влево (не вправо) и иЛИ-байты в ней в своем «нормальном» (ООН смещенной) место:

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 

Оба они могут быть написаны лаконично, как в:

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

или

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

При перемещении влево, например byte2 << 8, не становится ли 00000000 ?? @nobody –

+0

@Maximillan По существу 'x << 1' -' x * 2', а 'x << 2' -' x * 4' ... или вообще 'x << k' is' x * 2^k' (где '^' означает возведение в степень). 'x >> k' - деление по степеням двух. Для вычисления 'byte2 << 8'' byte2' расширяется («продвигается») на 'int'. Если вы сохраните результат в 'char', он будет усечен, и вы получите' 00000000'. Но если вы присваиваете результат «int», биты сохраняются, и вы получите «00000000 00000000 11001100 00000000». (Сравните «целые акции»/«обычное арифметическое преобразование» в стандарте C для деталей gory, то, что я написал, вероятно, еще упрощено.) – nobody

+0

большое вам спасибо! Ясно объяснено! –

Смежные вопросы