1

次の方法でビットNを設定できることを知っています。

VALUE |= 1 << N;

または、次の方法でビット N をクリアします。

VALUE &= ~(1 << N);

しかし、ビット N を「書き込む」(セットまたはクリアしない) 最も効率的な方法は何ですか? たとえば、関数があります:

__inline void writeBit(char &value, int N, bool state)
{
    if(state)
        value |= 1 << N;
    else
        value &= ~(1 << N);
}

どうにかして if/else ステートメントを取り除き、代わりに二項演算子とシフト演算子のみを使用してこれを行うことはできますか?

4

2 に答える 2

2

Bit Hacksのページでは、次の式を使用することを提案しています。

value ^= (-state ^ value) & (1 << N);

の宣言をからにstate変更する必要があります。boolint

このトリックは、負の数の 2 の補数表現を使用するコンピューターで機能します。単項マイナス-stateは状態1を 1 で構成される数に変更し、ゼロを変更しないためです。

スーパースカラー CPU の代替案は次のようになります。

value = (value & ~(1 << N)) | (-state & (1 << N));
于 2013-10-07T00:19:54.033 に答える
1

私は簡単な解決策に行きます:

inline void writeBit(char &value, int N, bool state)
{
   value &= ~(1 << N); // Unconditional clear. We don't care about old value.
   value |= char(state) << N; // Unconditional set to intended value. 
}

これは非常に明確で一般的であるため、適切なオプティマイザーは意図を認識し、最適なソリューションを使用します。に応じて、2 つの命令のいずれかが役に立たなくなりますが、state無害でもあります。これは、コード内のブランチよりも優れています。

オプティマイザーがそれらをすべて同じように最適化しない限り、これはdasblinkenlightの方法のいずれよりも優れていると思います。

于 2013-10-07T10:34:23.910 に答える