我试图找到一种有效的方法来检查整数是否为零而不跳动。
我有两个整数变量in
和out
。如果in
为零,我希望out
为零。如果in
不为零,我想成为一个。
如果有帮助,我知道in
将为零或2的幂(仅一个置位)。我也知道,最高位和最低位都没有设置。
我可以做的很明显:out = (in == 0 ? 0 : 1);
但这意味着跳伞是很昂贵的。
我可以做类似out = (in * 0xFFFFFFFF) >> 63;
的事情。这意味着我要避免的乘法和移位,但是我找不到办法。也许不可能。
还有其他方法我可以不跳而只使用按位运算符和算术吗?
谢谢
答案 0 :(得分:6)
这在架构上会有所不同,但是代码不会编译为在Intel CPU上的跳转。
此代码:
int square(int in) {
int out = (in != 0);
return out;
}
编译为:
square(int):
xor eax, eax
test edi, edi
setne al
ret
或:
square, COMDAT PROC
xor eax, eax
test ecx, ecx
setne al
ret 0
square ENDP
由msvc,clang和gcc与O2组成:
这只是没有优化的跳转,您将永远不会做。
答案 1 :(得分:2)
我还发现有必要这样做,将一个length-2数组索引为0(零值)和1(非零值)。
将int转换为bool,然后返回int。除了2018年之前的MSVC之外,这几乎不会在我尝试过的所有编译器(gcc,clang,最新的MSVC)上都起作用。我建议您检查汇编代码以确保在您的平台上。
int one_if_nonzero_else_zero(int value) { return (bool) value; }
编辑:这不能满足您的约束“仅使用按位运算符和算术”,但是此转换利用了程序集优化的优势,并且非常有效。
编辑:您的“显而易见”解决方案out = (in == 0 ? 0 : 1);
产生的汇编代码与Jerry Jeremiah和我本人在gcc,clang和msvc上发布的解决方案相同。优化后不跳!我建议您使用它来保持清晰。
答案 2 :(得分:0)
我有两个整数变量
in
和out
。如果in
为零,我想out
为零。如果in
不为零,我希望out
为一。
尝试一下:
int in = ...;
int out = !!in;
C ++具有从int
到bool
的隐式转换,因此当in
为0时,作为bool
的{{1}}将是false
,否则为in
。
然后true
将是!false
,而true
将是!true
。
然后false
将是!true
,而false
将是!false
。
然后,还有一个从true
到bool
的隐式转换,因此int
作为true
将为1,而int
将为0
因此,false
为0时out
为0,否则为1。