我来这里要求伎俩。 我有一个32位整数(即4个字节)。我想为每个字节测试零,如果其中一个为真,则返回true。 e.g。
int c1 = 0x01020304
cout<<test(c1)<<endl; // output false
int c2 = 0x00010203
cout<<test(c2)<<endl; // output true
int c3 = 0xfffefc00
cout<<test(c3)<<endl; // output true
在最少的CPU周期中是否有任何技巧?
答案 0 :(得分:3)
您可以通过屏蔽&
操作中的每个字节并将结果与零进行比较来测试它:
bool hasZeroByte(int32_t n) {
return !(n & 0x000000FF)
|| !(n & 0x0000FF00)
|| !(n & 0x00FF0000)
|| !(n & 0xFF000000);
}
答案 1 :(得分:3)
着名的bithacks页面有几种方法
bool hasZeroByte(unsigned int v)
{
return ~((((v & 0x7F7F7F7F) + 0x7F7F7F7F) | v) | 0x7F7F7F7F);
}
或
bool hasZeroByte = ((v + 0x7efefeff) ^ ~v) & 0x81010100;
if (hasZeroByte) // or may just have 0x80 in the high byte
{
hasZeroByte = ~((((v & 0x7F7F7F7F) + 0x7F7F7F7F) | v) | 0x7F7F7F7F);
}
最快的方式:
#define haszero(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL)
很难理解,如果你想要清晰,屏蔽掉每个字节并像在dasblinkenlight的答案中那样检查
答案 2 :(得分:2)
执行此操作的最快方法可能是使用strnlen
,因为大多数编译器都会对此进行优化,以使用低级指令在字符串中查找零字节。
bool hasZeroByte(int32_t n) {
return strnlen(reinterpret_cast<char *>(&n), 4) < 4;
}
如果您想要更明确一些,可以使用记录的memchr
函数来完全按照您的要求执行:
bool hasZeroByte(int32_t n) {
return memchr(reinterpret_cast<void *>(&n), 0, 4) != nullptr;
}
对于那些不相信这个答案的人,请随时查看glibc
implementation of strlen
,看看它已经在其他答案中做了所有提到的一些麻烦的技巧。
另见: