使用位操作优化检查

时间:2018-07-11 12:13:43

标签: c++ c optimization bit-manipulation vectorization

我将以下代码片段作为一种算法的一部分。我使用pi_pipi_stack[i]isis_stack[i](全部unsigned int)作为一组大小为{{1 }}。

  • N是一个掩码,用于确定N_MASK=(1<<N)-1的哪一部分有用。
  • unsigned int

我想确定是否存在子集N_POLICY=(1<<N),使得pi_成立。目前,我正在迭代所有可能的子集。 ((pi_^pi) & (is^N_MASK)) == 0 && ((pi_^pi_stack[i]) & is_stack[i]) == 0 && ((pi_^pi) & is)ispi_stack[i]is_stack[i]之间应该是什么关系,以便不存在这样的pi

pi_

我想到了: bool flag=false; for(uint pi_=0; pi_<N_POLICY && !flag; pi_++){ flag = flag || ( ((pi_^pi) & (is^N_MASK)) == 0 && ((pi_^pi_stack[i]) & is_stack[i]) == 0 && ((pi_^pi) & is) ); } 但这行不通,但是可以让我对所要寻找的东西有所了解。该代码旨在替换上面的循环。

1 个答案:

答案 0 :(得分:2)

除了迭代pi_stack[i]is_stack[i]之外,无需循环即可直接计算解决方案。

格式为(pi_ ^ v) & m的条件要求pi_vm中设置了该位的每个位位置具有相同的值。我们可以这样表示:

uint RequiredBits   = m; // Mask of bits that must have certain values.
uint RequiredValues = v & m; // Record of the values the bits must have.

您的测试显示了两个这样的标准:

((pi_ ^ pi) & (is ^ N_MASK)) == 0

((pi_ ^ pi_stack[i]) & is_stack[i]) == 0

假设我们已经代表了第一个标准:

uint RequiredBits   = is ^ N_MASK;
uint RequiredValues = pi & RequiredBits;

现在我们还需要第二个条件。为简便起见,让我们分配v = pi_stack[i]m = is_stack[i]。我们有两个问题:是否可以同时满足两个条件?而且,如果是的话,两者的组合是哪个标准?

如果mRequiredBits没有任何共同的设置位,那么就没有冲突,因为pi_可以在它们各自控制的任何位位置自由获得所需的值。如果它们确实具有共同的设置位,则vRequiredValue在这些位中必须相同,因为pi_不能在同一位置同时包含0和1。因此,冲突测试是:

if (((v ^ RequiredValues) & (m & RequiredBits)) != 0)
    print/exit/return/whatever; // Report no solution is possible.

如果两个条件一致,那么我们可以将它们组合:

RequiredValues = RequiredValues | (v & m);
RequiredBits   = RequiredBits | m;

如果针对pi_stack[i]的不同值,有多个涉及is_stack[i]i的条件实例,则可以重复上述操作。

最后,我们有了条件pi_ ^ pi) & is。这表示pi_pi必须在is中设置了该位的至少一个位位置不同。此职位必须是未在RequiredBits中设置的职位,因为较早的条件要求pi_pi在那些职位中必须相同,并且{{1 }}和pi_相同且在同一位置不同。

因此,pipi_必须至少相差pi中的一位。如果is & ~RequiredBits为零,这是不可能的,因为在is & ~RequiredBits中没有ispi_可以相差的位置。因此我们测试:

pi

否则,我们在if ((is & ~RequiredBits) == 0) print/exit/return/whatever; // Report no solution is possible. pi_的所需位置(按pi)和可用位置(按is)中构造一些差异:

~RequiredBits

然后一个解决方案是:

uint Differences = ~pi & (is & ~RequiredBits);

所有可能的解决方案都可以通过以下方式进行迭代:

  • 通过所有可能的值迭代uint pi_ = RequiredValues | Differences; pi_以外的所有位。
  • 通过is | RequiredBits以外的所有可能值来迭代pi_is & ~RequiredBits的所有位(因为这是pi & (is & ~RequiredBits)指定的所有位都具有它们在is & ~RequiredBits中的值,但我们希望至少有一个不同的值。