在进行一些操作和删除分支时,不时会弹出以下问题:
假设我有一个整数二进制标志f
,可以是0
或1
。我怎样才能将其分别-1
和1
(或相反的方式,由您自行决定 - 通常任何一个都可用)。一种常见的方式是这样的:
int i = 2*f - 1;
但这使用了加法和乘法。它可以做得更快吗?
在进行一些操作和删除分支时,不时会弹出以下问题:
假设我有一个整数二进制标志f
,可以是0
或1
。我怎样才能将其分别-1
和1
(或相反的方式,由您自行决定 - 通常任何一个都可用)。一种常见的方式是这样的:
int i = 2*f - 1;
但这使用了加法和乘法。它可以做得更快吗?
Your original is actually pretty good - a reasonable optimiser will turn it into:
int i = f + f - 1;
and for example on x86 this can be compiled down to a single instruction.
好吧,对于初学者来说,你可以做
int i = (f << 1) - 1;
另外,你可以试试
int i = f - (!f);
也许我错过了一些东西,但是有什么问题if (i == 0) i = -1;
?
[编辑:没关系,我错过了一些东西。您希望结果为单独的有符号整数。]
x
要基于 flag有条件地否定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;
要有条件地加或减一个数字,只需有条件地否定它,然后总是使用加法。