Это типичный бит-сдвигающий/бит-маскирующий материал. Вот как установить начальное значение:
uint32_t value = ((part1 & 0xF) << 28)
| ((part2 & 0x3) << 26)
| ((part3 & 0xFFF) << 14)
| ((part4 & 0x3) << 12)
| (part5 & 0xFFF);
Каждая строка использует операции побитового И (&)
очистить верхние биты каждой части, так что не переполнить его выделенную битовую ширину в пределах конечного значения. Например, если part4 был 0xFF, и вы забыли & 0x3
, тогда верхние 6 бит части 4 (0xFC) будут разливаться в область для части 3. Затем часть сдвигается (<<)
до ее конечного местоположения и побитового OR'd (|)
с остальными частями.
Некоторые разработчики выполняют одно и то же с помощью битовых полей, но я не рекомендую этот подход из-за потенциальных проблем с переносимостью.
Большинство (все?) Других ответов здесь до сих пор забыли побитно-и часть решения. Их ответы приведут к ошибкам, если значения детали превысят указанную ширину бита.
Если вы хотите обновить определенную часть значения, вам понадобится еще немного маскирования по битам по-по-битовому и побитовому-ИЛИ. Например, чтобы обновить part4 вы могли бы сделать это:
value &= ~(0x3 << 12); /* Clear the part4 region */
value |= (part4 & 0x3) << 12; /* Set the part4 region to the new value */
Это первая строка немного сложнее, если вы новичок в bitwork в C. Он говорит, принять 0x3 и перенести его на 12 (результат = 0x00003000) , выполнить поразрядное дополнение (result = 0xFFFFCFFF) и установить значение, равное самому поразрядному - AND'd с этим результатом. Вот как вы очищаете область part4 от значения ... потому что вы побито - и в этой области с нулем результат состоит в том, что область теперь равна нулю.
Вторая строка устанавливает обнуленную область part4 в новое значение, как мы это делали выше при установке начального значения.
Используйте сдвиг и бит-мудрый ИЛИ. –