转移操作

时间:2009-02-23 18:43:39

标签: c++ stl bit-manipulation

我看到其中一个伙伴stackoverflower张贴了以下内容,这让我感到茫然。

有人会解释以下代码段中的转换操作:

std::vector<bool> a;
a.push_back(true);
a.push_back(false);
//...
for (auto it = a.begin(); it != a.end();) // see 0x for meaning of auto
{
    unsigned b = 0;
    for (int i = 0; i < 8*sizeof(b); ++i)
    {
        b |= (*it & 1) << (8*sizeof(b) - 1 - i);
        ++it;
    }
    // flush 'b'
}

3 个答案:

答案 0 :(得分:3)

8 * sizeof(b)是可以存储在'b'中的位数(这是一个无符号整数,通常是32位或64位)。

代码正在做的是它将向量'a'中的布尔值打包成'b'中的位。

“* it&amp; 1”如果*处的布尔值为TRUE则计算为1,否则为0.然后该位向左移位32位减去1减去索引'i',即从0向左移位到31位。这意味着现在'a'的第一个元素将控制'b'上的最高有效位(左移31),第二个元素是'b'上的第二个最高有效位(左移30)等。请注意,在C中移位是算术的,即不管字节或比特顺序如何,x <&lt;&lt; 1总是x * 2.

因此,例如,如果您的向量具有第一个和第30个元素集,则“b”应该在当天结束时包含二进制数10000000 00000000 00000000 00000100。

答案 1 :(得分:0)

antti.huima的回答对我来说是正确的。

但是程序中可能存在错误。外部循环从a.begin到a.end,但是内部循环增加“it”,无论这是否导致“it”超过a.end。

如果你传递一个“奇数”大小的矢量,比如33个条目,那么结果可能不正确。

如果向量的大小是保证的(但也许应该测试长度是有效的),这可能不是错误。

答案 2 :(得分:0)

那里发生了什么:

(*it & 1)

这应该是0或1,具体取决于bool是真还是假;但请注意,bool总是0或1,所以这可能只是(无符号)*它

<< (8*sizeof(b) - 1 - i)

这是一个移位,它将位从最左边的位置移动到左边的 i -th。我们正在移动一个最多有一位设置的数字,所以这将设置 i - 最左边的位。其余的位为零。

b |= ...

这将在b中设置那些在RHS中打开的位。

i++;

转到下一个输入数字。小心保持在输入范围内。

这意味着整个事物将在b中设置位,对应于真实的矢量元素。