少し手を加えてブランチを削除すると、次の問題が時々発生します。
整数のバイナリフラグf
があるとします。これは0
または1
です。どうすればこれをそれぞれ-1
に1
(または逆に、あなたの裁量で-どちらか一方を使用できるように)変換できますか?一般的な方法は次のとおりです。
int i = 2*f - 1;
しかし、これは加算と乗算を使用します。もっと速くできるでしょうか?
少し手を加えてブランチを削除すると、次の問題が時々発生します。
整数のバイナリフラグf
があるとします。これは0
または1
です。どうすればこれをそれぞれ-1
に1
(または逆に、あなたの裁量で-どちらか一方を使用できるように)変換できますか?一般的な方法は次のとおりです。
int i = 2*f - 1;
しかし、これは加算と乗算を使用します。もっと速くできるでしょうか?
さて、初心者のためにあなたはすることができます
int i = (f << 1) - 1;
また、あなたは試すことができます
int i = f - (!f);
あなたのオリジナルは実際にはかなり良いです-合理的なオプティマイザーはそれを次のように変えます:
int i = f + f - 1;
たとえば、x86では、これを1つの命令にコンパイルできます。
何かが足りないかもしれませんが、何が問題なのif (i == 0) i = -1;
ですか?
[編集:気にしないでください、私は何かが欠けています。結果を別の符号付き整数にする必要があります。]
x
フラグに基づいて条件付きで否定するにf
は、次のようにします。
int mask = f - 1; // negate if f == 0, don't negate if f == 1
x = (x ^ mask) - mask;
またはこれ:
int mask = -f; // negate if f == 1, don't negate if f == 0
x = (x ^ mask) - mask;
条件付きで数値を加算または減算するには、条件付きで数値を否定し、常に加算を使用します。