N 和 (1<<x) == 什么时候为真?

When does N & (1<<x) == true?

本文关键字:lt 什么时候      更新时间:2023-10-16

我最近一直在研究使用位运算生成子集的完整搜索,所以我偶然发现了以下代码:

for(int b = 0; b < (1<<n); b++) {
    vector<int> subset;
    for(int i = 0; i < n; i++) {
        if( b&(1<<i)) subset.push_back(i);
    }
    //use subset here
}

此代码用于查找一组n元素的所有子集。我对这部分感到困惑

b&(1<<i)

如果b的第 i 位是0,这显然是错误的,但我不明白为什么如果第 i 位btrue的,为什么它会true,我的意思是结果不会只是2 i的幂(因为它不等于 1,即真的, 应该返回false(?

变化:除此之外,我现在注意到我知道任何与零不同的数都被认为是true,如果x0N是奇数,或者x>0N是偶数,则N & (1<<x) == true为真,因为==优先于&,所以N & (1<<x) == true解析为N & ( (1<<x) == true )

你有一个小小的误会...

因为它不等于 1,即 true,应该返回 false(

事实是:只有0被转换为false而所有其他数字都变得true

如果b的第 i 位是 0,这显然是错误的,但我不明白为什么如果第 i 位btrue的,为什么它会true,我的意思是结果不会2 i的幂(因为它不等于 1,即真的, 应该返回false (?

你在这里的错误不是1true而所有其他的都是false. 在 C++ 0false,所有其他值都true

回想一下,当在 C 或 C++ 中使用数值表达式时,在需要逻辑表达式的地方(如 if s 或 while s(中使用数值表达式时,表达式结果将隐式地与零进行比较。返回零的表达式表示"假",而返回非零的表达式表示"真"。他们不需要返回1 *

现在回想一下,1 << i构造一个二进制表示的数字,该数字在第 i 个位置有一个1。当位置 i 处的第 b 位为零时,执行具有此类数字b的数字&将产生零。当位置ib为 1 时,表达式将生成一个非零值,该值被 if 语句解释为"true"。

* 当 C 或 C++ 计算一个逻辑表达式时,例如 !&& 时,它会产生1,而不是任意的非零数。

这是一个非常常见的混淆,你混合了两件事:

  • 布尔到整数的转换:true转换为 1,false转换为 0
  • 整数到布尔值的转换:0转换为false,其他任何内容都转换为true

因此,当您使用表达式时,结果int ifwhile或任何其他需要布尔值的语句,您将隐式将其转换为bool因此第二种情况。此代码:

if( b&(1<<i)) subset.push_back(i);

在逻辑上与:

bool flag = b&(1<<i);
if( flag ) subset.push_back(i);