Ete*_*ner 25 c bit-manipulation
x使用合法运算符检查数字是否为非零值!.
例如:isNonZero(3) = 1,isNonZero(0) = 0
法律行动: ~ & ^ | + << >>
if,else,for等不能使用.int4个字节.int isNonZero(int x) {
return ???;
}
Run Code Online (Sandbox Code Playgroud)
使用!它将是微不足道的,但我们如何不使用!?
rus*_*lik 41
adamk函数的对数版本:
int isNotZero(unsigned int n){
n |= n >> 16;
n |= n >> 8;
n |= n >> 4;
n |= n >> 2;
n |= n >> 1;
return n & 1;
};
Run Code Online (Sandbox Code Playgroud)
最快的一个,但是在组装中:
xor eax, eax
sub eax, n // carry would be set if the number was not 0
xor eax, eax
adc eax, 0 // eax was 0, and if we had carry, it will became 1
Run Code Online (Sandbox Code Playgroud)
类似于汇编版本的东西可以用C编写,你只需要使用符号位和一些差异.
编辑:这是我在C中能想到的最快的版本:
1)对于负数:如果设置了符号位,则该数字不为0.
2)对于积极的:0 - n将是否定的,并且可以按照案例1进行检查.我没有-在合法操作列表中看到,所以我们将使用~n + 1.
我们得到了什么:
int isNotZero(unsigned int n){ // unsigned is safer for bit operations
return ((n | (~n + 1)) >> 31) & 1;
}
Run Code Online (Sandbox Code Playgroud)
ust*_*sta 11
int isNonZero(unsigned x) {
return ~( ~x & ( x + ~0 ) ) >> 31;
}
Run Code Online (Sandbox Code Playgroud)
假设int是32位(/*EDIT:这部分不再适用,因为我将参数类型更改为无符号*/并且有符号的移位与无符号移位的行为完全相同).
为什么让事情复杂化?
int isNonZero(int x) {
return x;
}
Run Code Online (Sandbox Code Playgroud)
它的工作原理是因为C约定是每个非零值都表示正确,因为isNonZero返回一个合法的int.
有人认为,isNonZero()函数应该为输入3返回1,如示例中所示.
如果您使用的是C++,它仍然像以前一样简单:
int isNonZero(int x) {
return (bool)x;
}
Run Code Online (Sandbox Code Playgroud)
现在函数返回1,如果你提供3.
好吧,它不适用于C错过适当的布尔类型.
现在,如果你认为int是32位且允许+:
int isNonZero(int x) {
return ((x|(x+0x7FFFFFFF))>>31)&1;
}
Run Code Online (Sandbox Code Playgroud)
在某些体系结构上,您甚至&1可以通过将x转换为unsigned(具有空运行时成本)来避免最终结果,但这是未定义行为,因此依赖于实现(取决于目标体系结构是使用带符号还是逻辑右移).
int isNonZero(int x) {
return ((unsigned)(x|(x+0x7FFFFFFF)))>>31;
}
Run Code Online (Sandbox Code Playgroud)