0

仲間のstackoverflowerの1人が投稿した次の投稿を見て、ちょっと唖然としました。

誰かが次のコード スニペットでシフト操作を説明しますか?

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

3 に答える 3

3

8 * sizeof(b) は、'b' に格納できるビット数です (これは unsigned int であり、通常は 32 または 64 ビットです)。

コードが行っていることは、ブール値をベクトル 'a' にパックして 'b' のビットにすることです。

"*it & 1" は、*it のブール値が TRUE の場合は 1 に評価され、それ以外の場合は 0 に評価されます。次に、ビットは 32 ビットから 1 からインデックス 'i' を引いた値、つまりゼロから 31 ビットに左にシフトされます。これは、'a' の最初の要素が 'b' の最上位ビット (左シフト 31) を制御し、2 番目の要素が 'b' の 2 番目の最上位ビット (左シフト 30) などを制御することを意味します。シフトは算術演算です。つまり、バイトまたはビットの順序に関係なく、x << 1 は常に x * 2 です。

たとえば、ベクトルに 1 番目と 30 番目の要素セットがある場合、'b' には 1 日の終わりまでに 2 進数 10000000 00000000 00000000 00000100 が含まれている必要があります。

于 2009-02-23T18:49:12.687 に答える
0

antti.huimaの答えは私には正しいように見えます。

ただし、手順にバグがある可能性があります。外側のループはa.beginからa.endに移動しますが、内側のループは、これによって「it」がa.endを通過するかどうかに関係なく、「it」をインクリメントします。

「奇数」サイズ、たとえば33エントリのベクトルを渡すと、結果が正しくなくなる可能性があります。

ベクトルのサイズが保証されている場合、これはバグではない可能性があります(ただし、長さが有効であることをテストする必要があります)。

于 2009-02-23T18:55:23.563 に答える
0

そこで何が起こっているのか:

(*it & 1)

これは、ブール値がtrueまたはfalseであるかどうかに応じて、0または1になります。ただし、boolは常に0または1であるため、これは(符号なし)*itである可能性があることに注意してください。

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

これはシフトであり、ビットを右端の位置から左からi番目の位置に移動します。最大で1ビットが設定されている数値をシフトしているため、これにはi番目の左端のビットが設定されているかどうかが示されます。残りのビットはゼロです。

b |= ...

bこれにより、RHSでオンになっているビットがに設定されます。

i++;

次の入力番号に移動します。入力範囲内にとどまるように注意してください。

bこれは、真のベクトル要素に対応して、全体がビットを設定することを意味します。

于 2009-02-23T18:57:03.450 に答える