C按位OR返回“f”

时间:2014-01-22 20:40:22

标签: c bitwise-or

我正在做一个非常简单的计算机科学作业,围绕着C中的按位运算符,但我遇到了一个问题,我不知道为什么会发生这种情况。这是我正在运行的代码。

    #include <stdio.h>

int main(int argc, char *argv[]){
    int bitPattern1 = 0x10011001;
    int bitPattern2 = 0x01100110;
    int bitPattern3 = 0xFFFFFFFF;
    int bitPattern4 = 0x00000000;

    /* pair 1 */
    printf("bitPattern1 &  bitPattern2 = %x\n", bitPattern1 &  bitPattern2);
    printf("bitPattern1 && bitPattern2 = %x\n", bitPattern1 && bitPattern2);

    /* pair 2 */
    printf("bitPattern1 |  bitPattern2 = %x\n", bitPattern1 |  bitPattern2);
    printf("bitPattern1 || bitPattern2 = %x\n", bitPattern1 || bitPattern2);

    /* pair 3 */
    printf("bitPattern1 &  bitPattern3 = %x\n", bitPattern1 &  bitPattern3);
    printf("bitPattern1 && bitPattern3 = %x\n", bitPattern1 && bitPattern3);

    /* pair 4 */
    printf("bitPattern1 |  bitPattern3 = %x\n", bitPattern1 |  bitPattern3);
    printf("bitPattern1 || bitPattern3 = %x\n", bitPattern1 || bitPattern3);

    /* pair 5 */
    printf("bitPattern2 &  bitPattern4 = %x\n", bitPattern2 &  bitPattern4);
    printf("bitPattern2 && bitPattern4 = %x\n", bitPattern2 && bitPattern4);

    /* pair 6 */
    printf("bitPattern2 |  bitPattern4 = %x\n", bitPattern2 |  bitPattern4);
    printf("bitPattern2 || bitPattern4 = %x\n", bitPattern2 || bitPattern4);

    return 0;
} 

问题发生在第4对的第一部分,它返回以下结果:

bitPattern1 |  bitPattern3 = ffffffff
bitPattern1 || bitPattern3 = 1

为什么按位运算符返回“f”s我查找了文档,虽然OR运算符返回1或0但似乎该示例应该返回“11111111”。这与十六进制数字有关吗?我一直无法在谷歌上找到任何东西。

4 个答案:

答案 0 :(得分:2)

首先,OR的输入是FFFFFFFF的十六进制表示法,这意味着在二进制(按位)术语中它是11111111111111111111111111111111。即它比你引用的要多得多1(确切地说是32位)。

其次,有问题的按位OR应该确实以二进制表示法返回1111111...1。而这正是它的回报。但是当您以 hex 表示法打印结果时,您会得到FFFFFFFF。您使用x中的printf格式说明符明确请求了十六进制表示法。

不幸的是,printf没有用于生成二进制表示法的格式说明符。但是,将十六进制转换为二进制是一项微不足道的任务,因为它是用四个二进制数字直接替换每个十六进制数字。 F代表1111,正如您所看到的那样,按位词,您的OR确实会产生11111111111111111111111111111111,就像它应该的那样。

答案 1 :(得分:1)

按位运算符对参数中的所有位进行操作,在执行操作时将每个位与其对应位匹配。由于您已分配bitPattern3 = 0xFFFFFFFF所有32位都已打开,因此对其进行按位或(|)将使所有位都切换为打开。

逻辑OR(||)会将参数视为true / false,并对它们执行简单的OR运算,返回true / false值

答案 2 :(得分:1)

ORAND运算符有两种形式,逻辑(|| and &&)和算术(| and &)。

逻辑ORAND将返回bool结果。这些是你的“英语式”连词。

算术ORAND在位级上工作,在每个相应的位上进行连接。

在前一种逻辑比较(|| and &&)的情况下,您通常会比较布尔值。例如:

bool shouldUpdate = (hasNetworkConnection && isNewerVersionAvailable);
bool isDifferentLocation = (location.X != this.X || location.Y != this.Y);

对于后一种算术比较的情况,这些通常使用enum的{​​{1}}值完成,如下所示:

Flags

在这种情况下,[Flags] enum AccessModeFlags { None = 0x0, Read = 0x1, Write = 0x2, ReadWrite = Read | Write } ReadWrite,因为它是0x3OR的按位0000 0001,从而产生0000 0010。< / p>

答案 3 :(得分:0)

这与您的问题相关,但行:

int bitPattern1 = 0x10011001;
int bitPattern3 = 0xFFFFFFFF;

导致实现定义的行为或引发实现定义的信号,因为值0x10011001和0xFFFFFFFF超出“int”的范围,假设您使用的是32位整数。

重要的是要理解当你编写这些行时,你并没有在变量中明确地存储该位模式。您将VALUE 4294967295存储在变量中,编译器可以选择它用于存储该值的位模式。它可以做任何它喜欢的事情,只要你访问它的价值就可以得到你所放的东西 - 尽管为了简单起见,这几天的计算机几乎都使用了两个补码表示。

在这种情况下,int的最大值为2147483647,因此您的分配超出范围。但是GCC已经决定通过猜测你想要分配导致二进制补码表示FFFFFFFF的任何值来处理这个问题。其他编译器可以在此时中止该程序并仍然符合C标准。

此外,您将“int”传递给%x,如果int为负,则会导致未定义的行为。 “%x”需要“unsigned int”。

您可以通过将所有“int”更改为“unsigned int”来避免这些问题。