这是典型的位移/位掩码的东西。以下是设置初始值的方法:
uint32_t value = ((part1 & 0xF) << 28)
| ((part2 & 0x3) << 26)
| ((part3 & 0xFFF) << 14)
| ((part4 & 0x3) << 12)
| (part5 & 0xFFF);
每一行都使用按位与(&) 来清除每个部分的高位,这样它就不会在最终值内溢出其分配的位宽。例如,如果 part4 是 0xFF 而您忘记了& 0x3,那么 part4 (0xFC) 的高 6 位将溢出到 part3 的区域。然后将零件(<<) 移动到其最终位置,并与其余零件按位或运算(|)。
一些开发人员通过位域完成同样的事情,但由于潜在的可移植性问题,我不推荐这种方法。
到目前为止,这里的大多数(全部?)其他答案都忘记了解决方案的按位与部分。如果零件值超过指定的位宽,他们的答案将导致错误。
如果要更新值的特定部分,则需要通过按位与和按位或进行更多位掩码。例如,要更新第 4 部分,您可以这样做:
value &= ~(0x3 << 12); /* Clear the part4 region */
value |= (part4 & 0x3) << 12; /* Set the part4 region to the new value */
如果您是 C 中的 bitwork 新手,那么第一行有点棘手。它表示取 0x3 并将其移位 12(结果 = 0x00003000),执行按位补码(结果 = 0xFFFFCFFF),并将值设置为相等与该结果进行按位与运算。这就是您清除值的第 4 部分区域的方式...因为您对该区域进行按位与零运算,结果是该区域现在为零。
第二行将归零的第 4 部分区域设置为新值,就像我们在上面设置初始值时所做的一样。