現在、次の問題に遭遇したツリー列挙子を作成中です。
私はマスクされたビットセット、つまりセットビットがマスクのサブセットであるビットセット、つまり0000101
マスク付き1010101
。私が達成したいのは、ビットセットをインクリメントすることですが、マスクされたビットに関してのみです。この例では、結果は0010000
。少し明確にするために、マスクされたビットのみを抽出します。つまり、0011
、それらを0100
そしてそれらを再びマスクビットに分配し、0010000
。
ビットスキャンとプレフィックスマスクの組み合わせを使用して手動で操作を実装する以外に、これを行うための効率的な方法を誰かが見ていますか?
キャリーを伝播するために、マスク以外のビットを1で埋めるだけです。
// increments x on bits belonging to mask
x = ((x | ~mask) + 1) & mask;
受け入れられた答えと比べて直感的ではありませんが、これはたった3つのステップで機能します。
x = -(x ^ mask) & mask;
これは、zchが示唆するように検証できます。
-(x ^ mask)
= ~(x ^ mask) + 1 // assuming 2's complement
= (x ^ ~mask) + 1
= (x | ~mask) + 1 // since x and ~mask have disjoint set bits
その後、受け入れられた回答と同等になります。
反復の順序がそれほど重要ではなく、デクリメント操作でニーズが満たされる場合、次の2つの操作のみを使用できます。
始めましょう
_x = mask
_
と前の値を取得します
x = (x - 1) & mask
_x - 1
_部分は、最後の非ゼロビットをゼロに変更し、下位ビットをすべて1に設定します。次に、_& mask
_部分は、マスクビットのみを残します。