3

我正在尝试使用无符号整数构造一个 32 位二进制值。这就是 32 位被分成几部分的方式

第 1 部分 = 4 位

第 2 部分 = 2 位

第 3 部分 = 12 位

第 4 部分 = 2 位

第 5 部分 = 12 位

我如何使用这些部件使用位移构造 32 位二进制值(无符号整数)有人可以帮忙吗

(不能只是移位......如果我想更新某些部分怎么办?)

4

3 回答 3

5

这是典型的位移/位掩码的东西。以下是设置初始值的方法:

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 区域设置为新值,就像我们在上面设置初始值时所做的一样。

于 2013-09-19T21:54:12.917 回答
5

正如您所建议的,您只需使用移位:

uint32_t x = (part1 << 28)
           | (part2 << 26)
           | (part3 << 14)
           | (part4 << 12)
           | (part5);
于 2013-09-19T17:03:39.253 回答
4

看起来你想要这个值:

part5 + (part4 << 12) + (part3 << 14) + (part2 << 26) + (part1 << 28)

(确保所有五个变量都是类型uint32_t或类似的。)

于 2013-09-19T17:03:18.420 回答