NOT对整数值进行操作

时间:2013-07-30 16:29:07

标签: c++ bit-manipulation tilde

我知道〜操作符不能操作。但我无法弄清楚以下程序的输出(-65536)。究竟发生了什么?

#include <stdio.h>

int main(void) {
  int  b = 0xFFFF;
  printf("%d",~b);
  return 0;
}

7 个答案:

答案 0 :(得分:9)

假设32位整数

int  b = 0xFFFF; => b = 0x0000FFFF
~b = 0xFFFF0000

现在设置了最高位。假设2s complement,这意味着我们有一个负数。反转其他位然后添加一位会产生0x0001000065536

答案 1 :(得分:4)

将16位值0xffff分配给32位整数b时,变量b实际上变为0x0000ffff。这意味着当您执行按位补码时,它变为0xffff0000,这与十进制-65536相同。

答案 2 :(得分:2)

它正在做一个按位补充,这个输出可以帮助你更好地理解发生了什么:

std::cout <<  std::hex << " b: " << std::setfill('0') << std::setw(8) <<  b
           << " ~b: " <<  (~b) << " -65536: " << -65536 << std::endl ;

我收到的结果如下:

b: 0000ffff ~b: ffff0000 -65536: ffff0000

所以我们将低16位设置为1,这给了我们0000ffff然后我们做一个补码,将低16位设置为0,将高16位设置为1给了我们ffff0000,它等于十进制的-65536

在这种情况下,由于我们正在使用按位运算,因此检查十六进制数据可以让我们深入了解正在发生的事情。

答案 3 :(得分:1)

C ++中的〜运算符是按位NOT运算符。它也称为按位补码。这会翻转已签名整数的位。

例如,如果你有

 int b = 8;
 // b in binary = 1000
 // ~b = 0111

这将翻转代表提供的初始整数值的位。

答案 4 :(得分:1)

结果取决于您的平台上的签名整数的表示方式。最常见的表示是使用“2s补码”算法表示负值的32位值。也就是说,负值-x由与无符号值2^32 - x相同的位模式表示。

在这种情况下,原始位模式设置了低16位:

0x0000ffff

按位否定清除这些位并设置高16位:

0xffff0000

将此解释为负数会得到值-65536

通常,当你搞乱按位运算时,你会想要使用无符号类型,以避免这种混淆。

答案 5 :(得分:0)

您的评论:

  

如果它不是'b'..那么输出应为0,但为什么-65536

建议你期待以下结果:

uint32_t  x = 0xFFFF;
uint32_t y = ~x;

0

对于逻辑非操作,情况确实如此:

uint32_t x = 0xFFFF;
uint32_t y = !x;

...但operator~不是逻辑 NOT,而是按位不是。有很大的不同。

对于非0值,逻辑返回0(对于真值,返回false),对于0值,返回1。

但是,按位不会反转给定值中的每个位。所以二进制NOT 0xF

0x0F:  00000000 11111111
~0x0F: 11111111 00000000

不是零,而是0xF0。

答案 6 :(得分:-1)

对于整数中的每个二进制数,按位NOT运算将所有1都变为0,并且所有0都变为1。

所以十六进制0xFFFF是二进制1111 1111 1111 1111(每个十六进制字符是4位,F,15,在所有四位中都是1s)

你设置一个32位整数,这意味着现在:

0000 0000 0000 0000 1111 1111 1111 1111

然后你没有,这意味着它是:

1111 1111 1111 1111 0000 0000 0000 0000

最高位是签名位(无论是正数还是负数),因此它给出一个负数。