简体   繁体   English

按位AND行为与预期不同?

[英]Bitwise AND behaves differently than expected?

#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;
}

The code above prints Hi. 上面的代码显示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;
}

The code above doesn't print anything. 上面的代码不显示任何内容。

Logically, you would think that a bitwise AND would mean that all the digits in binary would have to match in order to return true. 从逻辑上讲,您会认为按位与将意味着二进制中的所有数字都必须匹配才能返回true。 Instead, in reality, each digit in binary would have to be different for the condition to return false. 相反,实际上,二进制数的每个数字都必须不同,条件才能返回false。

I don't understand the point of bitwise AND. 我不明白按位与的意义。

I also understand that false is equivalent to 0 in C. 我也知道false在C中等于0。

It is a bitwise & . 这是按位& That means the result of the operation is the result of applying & bit by bit on the two operands. 这意味着运算的结果是对两个操作数逐位应用&的结果。

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

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

If you want all the bits to be equal, that's just == . 如果您希望所有位都相等,那就是== Or you would bitwise & it with 111111 或者你会按位&它有111111

Like Karthik said it's bitwise. 就像Karthik所说的那样。

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

The operator is bitwise, which means it compares the binary representation of two variables bit by bit. 运算符是按位的,这意味着它会逐位比较两个变量的二进制表示形式。 When you have 当你有

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

What happens is this: the bits of result are set based on the values of the bits in a and b . 这是什么情况: result的位是根据ab中的位的值设置的。 Each pair of corresponding bits in a and b is compared. 比较aba每对对应位。 Here, since the second and fifth bits (from the right) of both a and b are 1, ie, true, the comparison of those bits yields true, and correspondingly, the second and fifth bits in result are set to true as well. 这里,由于ab的第二和第五位(从右侧开始)均为1,即为true,因此这些位的比较将得出true,相应地, result中的第二和第五位也将设置为true。 Consequently, result is nonzero. 因此, result为非零。 This nonzero evaluation of a & b would cause "Hi" to print in your first example. 在第一个示例中, a & b这种非零值将导致打印"Hi"

In your second example: 在第二个示例中:

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

There is no case in the binary representation of 50 and 13 where corresponding bits are on: the first bit (from the right) is off in 50, on in 13; 在50和13的二进制表示中,没有对应的位处于打开状态的情况:第一个位(从右开始)在50中处于关闭状态,在13中处于开启状态; vice-versa for the second bit, and so on. 反之亦然,第二位,依此类推。 So the comparison of corresponding bits yields 0 in every case, and no corresponding bit is on in result . 所以对应比特的比较在每种情况下产生0,并且没有对应的位是在result Hence result evaluates to zero. 因此result评估为零。 This zero result causes "Hi" not to print in your second example. 此零结果导致在第二个示例中不打印"Hi"

As to the utility of this operator: bitwise operations are essential in embedded systems programming. 关于此运算符的实用程序:在嵌入式系统编程中,按位运算必不可少。 They are also extremely efficient for certain problems (eg a Sieve of Eratosthenes type program to generate primes). 它们对于某些问题也非常有效(例如,使用Eratosthenes筛分程序生成素数)。 The bitwise or is useful in cryptography. 按位或在加密中很有用。 The list goes on... 清单继续...

What is not clear to you is that in C, the number 0 is false, and any other number is true. 您不清楚在C中数字0是否为假,其他数字是否为真。

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

will do nothing, so if the bit-wise-and operation doesn't produce a single set bit, you have effectively computed an if statement that looks like 不会执行任何操作,因此,如果按位与运算未产生单个设置位,则您已经有效地计算了如下if语句

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

As everyone else has done a fine example of showing the bit operation, I'll defer to their math. 由于其他所有人都做了一个很好的示例,展示了位运算,因此我将遵循他们的数学原理。

Case 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")

Case 2: 情况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")

This is exactly the purpose of the bitwise and. 这正是按位与的目的。 It's mostly used for bit testing with masks. 它主要用于使用掩码进行位测试。 The net effect is to keep all the common 1s and zero out everything else. 最终结果是保留所有公共1,并将其他所有零清零。 Say, for instance you want to test if the 3rd bit is 1, you can just write 假设您要测试第3位是否为1,您可以编写

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

As Karthik said there are other methods to compare the operands the way you expected. 正如Karthik所说,还有其他方法可以按照您期望的方式比较操作数。

"Logically, you would think that a bitwise AND would mean that all the digits in binary would have to match in order to return true. Instead, in reality, each digit in binary would have to be different for the condition to return false." “在逻辑上,您会认为按位AND表示二进制中的所有数字都必须匹配才能返回true。实际上,二进制中的每个数字都必须不同,条件才能返回false。”

They don't have to be different. 他们不必不同。 AND would yield zero if both bits were zero, for instance. 例如,如果两个位均为零,则AND将产生零。 XOR is the logical operator that returns true only if the bits are different, and XNOR is the one that returns true only if they're the same. XOR是仅当位不同时才返回true的逻辑运算符,而XNOR是仅在它们相同时才返回true的逻辑运算符。 Since anything non-zero is true, then to get AND to return true you just need any one bit to be 1 in both of the operands. 由于任何非零值都是真实的,因此要使AND返回真实值,您只需要将两个操作数中的任何一位都设为1。 Conversely, it'll return false if neither of the operands have a 1-bit in common. 相反,如果两个操作数的公共位数都不为1,则它将返回false。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM