Optimization 在任意位位置查找数字的二进制表示形式

Optimization 在任意位位置查找数字的二进制表示形式,optimization,binary,bit-manipulation,Optimization,Binary,Bit Manipulation,在过去的一周里,我一直在努力解决这个问题,似乎我最终无法解决它。 给定任意64位无符号整数,如果它在任何位位置、任何位设置下包含31(0b11111)的二进制模式,则该数字有效,否则无效 例如: 0000 0000 0000 0001111有效 0000 0000 0000 0000 0011 1110有效 0000 0000 0000 0000 0000 0111 1100有效 0000 00001111000 0000有效 0000 0000 0011 1110 0000 00011 111

在过去的一周里,我一直在努力解决这个问题,似乎我最终无法解决它。 给定任意64位无符号整数,如果它在任何位位置、任何位设置下包含31(0b11111)的二进制模式,则该数字有效,否则无效

例如:

0000 0000 0000 0001111有效

0000 0000 0000 0000 0011 1110有效

0000 0000 0000 0000 0000 0111 1100有效

0000 00001111000 0000有效

0000 0000 0011 1110 0000 00011 1110有效等

此外:

0000 0000 1100 0000 0100 0000 1100 11000000 0100 0000 0001111有效

1110 0000 0100 0000 0011 0000 0000 0011 1110有效

0000 0000 1000 0010 0000 0010 0000 0000 0000 0010 0000 000 000111 1100有效

0000 0010 0000 0110 000011111000 0000 0100 0110 0000有效

0000 0000 0011 1110 0000 0011 0000 000 000 000 00011 1110有效等

但是:

0000 0000 1100 0000 0100 0000 11000 0000 0100 0000 11000 0000 0100 0000 1111无效

1110 0000 0000 0100 0000 0000 0011 0000 0000 0011 1100无效

0000 0000 1000 0010 0000 0010 0000 0000 0000 0010 0000 0000 0101 1100无效

0000 0010 0000 0110 0000 0000 0000 1111 0000 0000 0100 0110 0000无效

0000 0000 0011 1010 0000 0000 0011 0000 0000 1000 0000 0000 0000 0001 1110无效等

你说得对

但这只是问题的前半部分。第二个是,为了提高速度,它需要在没有循环或分支(已经完成)的情况下实现,只使用算术和/或逻辑、位操作类代码的一次检查

我能得到的最接近的是一个修改版本的位旋转黑客“确定一个字是否有一个零字节”()来检查五位的零块(否定11111)。但它仍然有能力仅检查固定的位块(位0到4、位5到9等),而不检查任何位位置(如上面的示例所示)

任何帮助都将不胜感激,因为我已经筋疲力尽了

Sz

实施 让我用稍微不同的表述重申你的目标:

我想检查一个整数是否包含5个连续的高位

根据这个公式,下面的解决方案解释了它自己。它是用C++编写的。
bool contains11111(uint64_t i) {
   return i & (i << 1) & (i << 2) & (i << 3) & (i << 4);
}
#包括
#包括
bool包含11111(uint64\u t i){
返回i&(i)实现
让我用稍微不同的表述重申你的目标:

我想检查一个整数是否包含5个连续的高位

从这个公式中,下面的解决方案说明了它自己,它是用C++编写的。
bool contains11111(uint64_t i) {
   return i & (i << 1) & (i << 2) & (i << 3) & (i << 4);
}
#包括
#包括
bool包含11111(uint64\u t i){

return i&(i Hello,请问没有分支是什么意思?循环实现(检查位。如果我们发现5个连续的,我们就完成了。否则运气不好)将进行59次比较。您当前的解决方案有多少次比较?(我认为需要做一些事情来减少所需的比较数量。然后你可以尝试将其一行写入一个逻辑子句)另外,你所说的“只有一个检查”是什么意思?我很可能会将for循环内联到一个“单个”中丑陋的检查。但不确定它是否有效。您好,请问没有分支是什么意思?循环实现(检查位。如果我们发现5个连续,我们就完成了。否则运气不好)将进行59次比较。您当前的解决方案有多少次比较?(我认为需要做一些事情来减少所需的比较数量。然后你可以尝试将其一行写入一个逻辑子句)另外,你所说的“只有一个检查”是什么意思?我很可能会将for循环内联到一个“单个”中丑陋的检查。不确定它是否有效。啊啊啊,就是这么简单。索科维,做得好,先生!简单而完美,适用于任何长度,任何模式。这正是我所寻找的。我意识到,在这个问题上陷入了一种不好的心态,我真正需要的是一种全新的、不同的观点。这是你们所提供的。谢谢你的努力!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,做得好,先生!简单而完美,适用于任何长度,任何模式。正是我所寻找的。我意识到,在这个问题上陷入了一种糟糕的心态,我真正需要的是一种全新的、不同的观点。这是你所提供的。谢谢你的努力!
#include <cinttypes>
#include <cstdio>

bool contains11111(uint64_t i) {
  return i & (i << 1) & (i << 2) & (i << 3) & (i << 4);
}

int main() {
  uint64_t testcases[] = {
      // valid
      UINT64_C(31),
      UINT64_C(62),
      UINT64_C(124),
      UINT64_C(260046848),
      UINT64_C(17451448556060734),
      UINT64_C(3382101189607455),
      UINT64_C(16142027170561130558),
      UINT64_C(36593945997738108),
      UINT64_C(145804038196167776),
      UINT64_C(17451654848708670),
      // invalid
      UINT64_C(3382101189607439),
      UINT64_C(16142027170561130556),
      UINT64_C(36593945997738076),
      UINT64_C(145804038187779168),
      UINT64_C(16325754941866014),
  };
  for (uint64_t i : testcases) {
    std::printf("%d <- %016" PRIx64 "\n", contains11111(i), i);
  }
}
1 <- 000000000000001f
1 <- 000000000000003e
1 <- 000000000000007c
1 <- 000000000f800000
1 <- 003e00000000003e
1 <- 000c0400cc00401f
1 <- e00400300000003e
1 <- 008202000020007c
1 <- 020600000f800460
1 <- 003e00300800003e
0 <- 000c0400cc00400f
0 <- e00400300000003c
0 <- 008202000020005c
0 <- 020600000f000460
0 <- 003a00300800001e