按位AND的行为与预期不同?

时间:2013-08-20 01:05:58

标签: c bit-manipulation

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int a = 50; // 110010
    int b = 30; // 011110

    if (a & b) {
        printf("Hi");
    }
    return 0;
}

上面的代码打印Hi。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int a = 50; // 110010
    int b = 13; // 001101

    if (a & b) {
        printf("Hi");
    }
    return 0;
}

上面的代码不会打印任何内容。

逻辑上,您会认为按位AND意味着二进制中的所有数字必须匹配才能返回true。相反,实际上,二进制中的每个数字必须不同才能使条件返回false。

我不明白按位AND的意思。

我也明白false在C中相当于0。

7 个答案:

答案 0 :(得分:2)

这是一个按位&。这意味着操作的结果是在两个操作数上逐位应用&的结果。

int a = 50; // 110010
int b = 30; // 011110

a & b == 010010 == 18 == true

如果你想让所有的比特都相等,那就是==。或者你可以用&

111111

答案 1 :(得分:2)

就像Karthik说的那样,这是明智的。

 int a = 50; // 110010               int a = 50; // 110010
 int b = 30; // 011110 &             int b = 13; // 001101 &
                ¯¯¯¯¯¯¯                             ¯¯¯¯¯¯¯
                010010 = 18                         000000 = 0 --false

答案 2 :(得分:1)

运算符是按位的,这意味着它逐位比较两个变量的二进制表示。当你有

int a = 50;           // 110010
int b = 30;           // 011110
int result = a & b;   // 010010

这是怎么回事:result的位是根据ab中的位值设置的。比较ab中的每对相应位。这里,由于ab的第二和第五位(来自右边)都是1,即为真,这些位的比较产生真,相应地,第二和第五位产生result也设置为true。因此,result非零。对a & b的非零评估会导致"Hi"在您的第一个示例中打印出来。

在你的第二个例子中:

int a = 50;           // 110010
int b = 13;           // 001101
int result = a & b;   // 000000

在50和13的二进制表示中没有相应的位开启的情况:第一位(从右边)在50中关闭,在13中开启;反之亦然,第二位,依此类推。因此,相应位的比较在每种情况下都会产生0,而在result中没有相应的位。因此result评估为零。这个零结果导致"Hi"无法在第二个示例中打印。

关于此运算符的实用性:按位运算在嵌入式系统编程中至关重要。它们对于某些问题也非常有效(例如,用于生成素数的Eratosthenes类型程序的Sieve)。按位或在密码学中很有用。名单继续......

答案 3 :(得分:1)

您不清楚的是,在C中,数字0为false,其他任何数字都为真。

if (0) {
  printf("hi");
}

将不执行任何操作,因此如果逐位和操作不会产生单个设置位,则您已经有效地计算了一个看起来像

的if语句
if (false) {
  printf("hi");
}

正如其他所有人都做了一个显示位操作的好例子,我会推迟他们的数学。

答案 4 :(得分:1)

案例1:

int a = 50; // 110010
int b = 30; // 011110
if (a & b) =>if (50 & 30) => if( 1 1 0 0 1 0 &     => if(010010)=> if(18)=>
                                 0 1 1 1 1 0     )
if(18)=>if(TRUE)=> printf("Hi")

案例2:

int a = 50; // 110010
int b = 13; // 001101
if (a & b) =>if (50 & 13) => if( 1 1 0 0 1 0 &     => if(000000)=> if(0)=>
                                 0 0 1 1 0 1   )
if(0)=>if(FALSE) => NO printf("Hi")

答案 5 :(得分:0)

这正是按位和的目的。它主要用于使用掩码进行位测试。净效应是保持所有常见的1并将其他所有内容归零。比如说,你想测试第3位是否为1,你可以写

if ( a & 4 /*0100*/ )
   // do something

正如Karthik所说,还有其他方法可以按照预期的方式比较操作数。

答案 6 :(得分:0)

“从逻辑上讲,你会认为按位AND意味着二进制中的所有数字都必须匹配才能返回true。相反,实际上,二进制中的每个数字必须是不同的才能返回条件假“。

他们不必有所不同。例如,如果两个位都为零,则AND将产生零。 XOR是逻辑运算符,仅当位不同时才返回true,而XNOR只有在它们相同时才返回true。因为任何非零都是真的,那么要使AND返回true,你只需要在两个操作数中都有1位为1。相反,如果两个操作数都没有共同的1位,它将返回false。