Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将二进制标志转换为-1或+;1尽可能快_C_Optimization - Fatal编程技术网

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;