【问题标题】:A "dynamic bitfield" in CC中的“动态位域”
【发布时间】:2011-03-01 01:37:20
【问题描述】:

在这个问题中,为简单起见,假设所有整数都是无符号的。

假设我想编写 2 个函数,pack 和 unpack,它们可以让您将较小宽度的整数打包成一个 64 位整数。但是,整数的位置和宽度是在运行时给出的,所以我不能使用 C 位域。

最快的就是举例说明。为简单起见,我将用 8 位整数进行说明:

             * *
bit #    8 7 6 5 4 3 2 1
myint    0 1 1 0 0 0 1 1

假设我想在位置 5(宽度为 2 的整数)“解包”。这是用星号标记的两个位。该操作的结果应该是 0b01。同样,如果我在宽度为 6 的位置 2 处打开包装,我会得到 0b100011。

我可以很容易地用左移位然后右移位来编写解包函数。

但我想不出一个清晰的方法来编写一个等效的“pack”函数,这会适得其反。

假设给定一个整数 0b11,将其打包到位置 5 和宽度 2 的 myint(从上方)中

             * *
bit #    8 7 6 5 4 3 2 1
myint    0 1 1 1 0 0 1 1

我想出的最好的方法是用 OR、> 连接很多位串。在我实施和测试它之前,也许有人看到了一个聪明的快速解决方案?

【问题讨论】:

    标签: c bit-manipulation


    【解决方案1】:

    在我的脑海中,未经测试。

    int pack(int oldPackedInteger, int bitOffset, int bitCount, int value) {
        int mask = (1 << bitCount) -1;
        mask <<= bitOffset;
        oldPackedInteger &= ~mask;
        oldPackedInteger |= value << bitOffset;
        return oldPackedInteger;
    }
    

    在你的例子中:

    int value = 0x63;
    value = pack(value, 4, 2, 0x3);
    

    当 0x63 是当前值时,在偏移量 4(两个位可用)处写入值“3”。

    【讨论】:

    • 是的。同样对于解包方法:OP 不需要使用“左移位后右移位”来解包;右移后跟 &amp; 就可以了。
    • @Luke:虽然我不太明白这个例子。解包结果是0x0b01和0xb100011是怎么回事?
    • @EboMike,第 5 位为 0,第 6 位为 1。
    • @EboMike,对其进行了测试,您的解决方案有效——谢谢! (1 的好技巧
    • @EboMike:为了后人的缘故,回答有关前提的评论。我一直在寻找一个普通的位域。 IE。将整数“打包”到一个位置不应更改整数中的其他内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    相关资源
    最近更新 更多