Страницы

Поиск по вопросам

суббота, 28 декабря 2019 г.

Как склеить 4 unsigned char в один unsigned int

#cpp #битовые_операции


Объясните, пожалуйста, как использовать битовый сдвиг для того, чтобы из четырёх
переменных unsigned char получить одну unsigned int, затем проделать обратное действие.
    


Ответы

Ответ 1



Последовательно в младшую часть int кладем очередной байт и сдвигаем влево на 8 бит. Что бы положить 1 байт в младшую часть используем логическое ИЛИ: unsigned char c1=5,c2=10,c3=98,c4=67; unsigned int I; I=c4; // c4 в младших 8и битах, остальные 0 I<<=8; // Сдвигаем int влево на 8 бит. Младшие 8 бит становятся 0, c4 становится в 9-16 битах. I|=c3; // Логическое ИЛИ заменяет 0 биты на те, что в байте c3 I<<=8; I|=c2; I<<=8; I|=c1; // Аналогично кладем остальные байты Для обратного действия сдвигаем int так, что бы нужный нам байт был самым младшим и маскируем остальные биты логическим И: c1=I & 0xFF; c2=(I>>8) & 0xFF; c3=(I>>16) & 0xFF; c4=(I>>24) & 0xFF; Только следим за порядком байт, на разных архитектурах числа в int принято класть по разному.

Ответ 2



Если вам нужно делать только такую операцию упаковки/распаковки то могу предложить вообще не используя битовые операции. unsigned int UI = 0x12345678; char *CC = (char *)(&UI); for (int i=3;i>=0;i--) cout << (int)CC[i]<<" "; unsigned char NC[4] = {120,86,52,18}; unsigned int TI = *(unsigned int *)(NC); cout << TI; Идея основана на явном преобразовании указателя. https://ideone.com/1P4tfc запускаемый пример.

Ответ 3



Например, вот так: int main() { unsigned char ch1 = 0x1; unsigned char ch2 = 0x2; unsigned char ch3 = 0x3; unsigned char ch4 = 0x4; unsigned int value = ch1; value <<= 8; value |= ch2; value <<= 8; value |= ch3; value <<= 8; value |= ch4; } Или чуть более общий вариант решения: #include const size_t BYTE_COUNT_IN_INT = 4; const size_t BITS_COUNT_IN_BYTE = 8; unsigned int getIntFromCharsArray(const std::array& charsArray) { unsigned int result = charsArray[0]; for (size_t i = 1; i <= BYTE_COUNT_IN_INT - 1; ++i) { result <<= BITS_COUNT_IN_BYTE; result |= charsArray[i]; } return result; } std::array getCharsArrayFromInt(unsigned int value) { std::array result; for (size_t i = 0; i <= BYTE_COUNT_IN_INT - 1; ++i) { result[BYTE_COUNT_IN_INT - i - 1] = value; value >>= BITS_COUNT_IN_BYTE; } return result; } int main() { const std::array charsArray = { 0x1, 0x2, 0x3, 0x4 }; unsigned int intFromCharsArray = getIntFromCharsArray(charsArray); auto charsArrayFromInt = getCharsArrayFromInt(intFromCharsArray); }

Ответ 4



Дополню. Если нужна именно конвертация и можно не использовать битовые сдвиги, то самое простое решение через union: union converter { unsigned int number; unsigned char bytes[4]; }; Число в байты: converter c; c.number = 123; // c.bytes[0] == 0xD2 // c.bytes[1] == 0x04 // c.bytes[2] == 0x00 // c.bytes[3] == 0x00 Байты в число: converter c; c.bytes[0] = 1; c.bytes[1] = 2; c.bytes[2] = 3; c.bytes[3] = 4; // c.number == 0x04030201 (big-endian)

Комментариев нет:

Отправить комментарий