这是典型的位移和按位掩码操作。这是如何设置初始值的方式:
uint32_t value = ((part1 & 0xF) << 28)
| ((part2 & 0x3) << 26)
| ((part3 & 0xFFF) << 14)
| ((part4 & 0x3) << 12)
| (part5 & 0xFFF);
每一行都使用位与运算符
(&)
来清除每个部分的高位,以便在最终值中不会溢出其分配的位宽。例如,如果part4是0xFF,并且您忘记了
& 0x3
,则part4的上6位(0xFC)将溢出到part3的区域。然后将该部分移位
(<<)
到其最终位置,并与其余部分进行按位或运算
(|)
。
有些开发人员通过位字段实现相同的功能,但由于潜在的可移植性问题,我不建议使用这种方法。
大多数(全部?)其他答案在解决方案中都忘记了位与运算部分。如果部件值超过指定的位宽度,则他们的答案将导致错误。
如果您想更新值的特定部分,您需要通过位与和位或进行更多的位掩码操作。例如,要更新part4,您应该这样做:
value &= ~(0x3 << 12);
value |= (part4 & 0x3) << 12;
如果你对C中的位运算不熟悉,第一行可能有些棘手。它的意思是将0x3左移12位(结果为0x00003000),执行按位补码(结果为0xFFFFCFFF),然后将值设置为自身按位与该结果。这是如何清除值的part4区域的...因为你在与零进行按位与操作,所以该区域的结果现在为零。
第二行将被清零的part4区域设置为新值,就像我们在设置初始值时所做的一样。