班次操作

发布于 2024-07-14 05:33:25 字数 420 浏览 2 评论 0原文

我看到了一位 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'
}

I saw the following posted by one of the fellow stackoverflower and it sort of dumbfounds me.

Would someone explain the shifting operations in the following code snippet:

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'
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

狼性发作 2024-07-21 05:33:25

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

该代码所做的是将向量“a”中的布尔值打包为“b”中的位。

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

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

8 * sizeof(b) is the number of bits that can be stored in 'b' (which is an unsigned int, i.e. typically 32 or 64 bits).

What the code is doing is that it is packing the boolean values in vector 'a' to become bits in 'b'.

"*it & 1" evalutes to 1 if the boolean value at *it is TRUE, otherwise 0. The bit is then shifted left 32 bits minus 1 minus the index 'i', i.e. shifted left from zero to 31 bits. This means now that the first element of 'a' will control the most significant bit on 'b' (left shift 31), the second element the second most significant bit on 'b' (left shift 30) etc. Note that in C the shifts are arithmetic, i.e. regardless of the byte or bit order, x << 1 is always x * 2.

So for example, if your vector has the first and the 30th element set, 'b' should contain by the end of the day the binary number 10000000 00000000 00000000 00000100.

你曾走过我的故事 2024-07-21 05:33:25

antti.huima 的答案在我看来是正确的。

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

如果您传递一个“奇数”大小的向量,例如 33 个条目,结果可能不正确。

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

antti.huima's answer looks right to me.

However there may be a bug in the procedure. The outer loop goes from a.begin to a.end, however the inner loop increments "it" regardless of whether this causes "it" to go past a.end.

if you pass a vector with an "odd" size, say 33 entries, the result could be incorrect.

This may not be a bug if the size of the vector is guarenteed (but maybe there should be test that the length is valid).

迷雾森÷林ヴ 2024-07-21 05:33:25

那里发生了什么:

(*it & 1)

这应该是 0 或 1,具体取决于 bool 为 true 或 false; 但请注意,布尔值始终为 0 或 1,因此这可能只是(无符号)*it

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

这是一个移位,它将位从最右边的位置移动到左侧的第 i 个位置。 我们正在移位一个最多设置了一位的数字,因此这将设置或不设置第i个最左边的位。 其余位为零。

b |= ...

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

i++;

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

这意味着整个事情将在 b 中设置位,对应于正确的向量元素。

What's happening there:

(*it & 1)

this should be 0 or 1 depending on the bool being true or false; note, however, that bools are always 0 or 1 so this could just be (unsigned)*it

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

This is a shift, which moves the bit from thi rightmost position to the i-th from the left. We are shifting a number which has at most one bit set, so this will have the i-th leftmost bit set or not. The rest of the bits are zero.

b |= ...

this sets those bits in b, that are on in the RHS.

i++;

Go to the next input number. Be careful to stay in the input range.

Which means the whole thing will set bits in b, corresponding to the vector elements that are true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文