在int中测试4个字节的零

时间:2015-05-04 15:59:56

标签: c++ algorithm bit

我来这里要求伎俩。 我有一个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周期中是否有任何技巧?

3 个答案:

答案 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,看看它已经在其他答案中做了所有提到的一些麻烦的技巧。

另见: