我正在尝试使用无符号整数构造一个 32 位二进制值。这就是 32 位被分成几部分的方式
第 1 部分 = 4 位
第 2 部分 = 2 位
第 3 部分 = 12 位
第 4 部分 = 2 位
第 5 部分 = 12 位
我如何使用这些部件使用位移构造 32 位二进制值(无符号整数)有人可以帮忙吗
(不能只是移位......如果我想更新某些部分怎么办?)
我正在尝试使用无符号整数构造一个 32 位二进制值。这就是 32 位被分成几部分的方式
第 1 部分 = 4 位
第 2 部分 = 2 位
第 3 部分 = 12 位
第 4 部分 = 2 位
第 5 部分 = 12 位
我如何使用这些部件使用位移构造 32 位二进制值(无符号整数)有人可以帮忙吗
(不能只是移位......如果我想更新某些部分怎么办?)
这是典型的位移/位掩码的东西。以下是设置初始值的方法:
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 部分区域的方式...因为您正在将该区域按位与零,结果是该区域现在为零。
第二行将归零的 part4 区域设置为新值,就像我们在上面设置初始值时所做的一样。
正如您所建议的,您只需使用移位:
uint32_t x = (part1 << 28)
| (part2 << 26)
| (part3 << 14)
| (part4 << 12)
| (part5);
看起来你想要这个值:
part5 + (part4 << 12) + (part3 << 14) + (part2 << 26) + (part1 << 28)
(确保所有五个变量都是类型uint32_t
或类似的。)