C 将二进制标志转换为-1或+;1尽可能快
在执行一些旋转和移除分支时,不时会出现以下问题: 假设我有一个整数二进制标志C 将二进制标志转换为-1或+;1尽可能快,c,optimization,C,Optimization,在执行一些旋转和移除分支时,不时会出现以下问题: 假设我有一个整数二进制标志f,它可以是0或1。如何将其分别转换为-1和1(或者相反的方式,由您自行决定-通常任何一种都是可用的)。一种常见的方法是: int i = 2*f - 1; 但它使用加法和乘法。它能做得更快吗?也许我遗漏了什么,但是如果(I==0)I=-1,有什么问题 [编辑:没关系,我遗漏了一些东西。您希望结果是一个单独的有符号整数。]好吧,对于初学者,您可以这样做 int i = (f << 1) - 1; 你的原创
f
,它可以是0
或1
。如何将其分别转换为-1
和1
(或者相反的方式,由您自行决定-通常任何一种都是可用的)。一种常见的方法是:
int i = 2*f - 1;
但它使用加法和乘法。它能做得更快吗?也许我遗漏了什么,但是如果(I==0)I=-1,
有什么问题代码>
[编辑:没关系,我遗漏了一些东西。您希望结果是一个单独的有符号整数。]好吧,对于初学者,您可以这样做
int i = (f << 1) - 1;
你的原创作品实际上相当不错——一个理性的乐观主义者会把它变成:
int i = f + f - 1;
例如,在x86上,可以将其编译为一条指令。要根据标志f
有条件地对x
求反,可以执行以下操作:
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;
有条件地加或减一个数,简单地有条件地否定它,然后总是使用加法。< /P>这不是乘法而是移位,或者说不同,如果你的编译器没有找到一个最佳的方法来完成整个事情,考虑使用另一个方法,你检查这个产生的汇编程序吗?您是否对不同的解决方案进行了基准测试?为什么您认为任何变体都会产生影响?答案是特定于平台和编译器的,您没有指定它们。我建议坚持使用
f?1:-1
除非你有针对目标平台的基准测试。Jens:最常见的情况是,它可能是一种添加,而不是转换。有趣的是,编译器的汇编程序,来自不同的解决方案,如果指令集支持的话,任何合适的编译器都应该能够将其转换为条件移动。我认为OP希望避免if,以免生成分支代码。
int mask = -f; // negate if f == 1, don't negate if f == 0
x = (x ^ mask) - mask;