C++ 非整数值运算

C++ 非整数值运算,c++,bit-manipulation,tilde,C++,Bit Manipulation,Tilde,我知道操作员不工作。但我无法理解以下程序(即-65536)的输出。到底发生了什么 #include <stdio.h> int main(void) { int b = 0xFFFF; printf("%d",~b); return 0; } #包括 内部主(空){ int b=0xFFFF; printf(“%d”,~b); 返回0; } > > P> > C++中的~运算符是位非算子。它也被称为按位补码。这是翻转有符号整数的位 例如,如果你有 int b =

我知道操作员不工作。但我无法理解以下程序(即-65536)的输出。到底发生了什么

#include <stdio.h>

int main(void) {
  int  b = 0xFFFF;
  printf("%d",~b);
  return 0;
}
#包括
内部主(空){
int b=0xFFFF;
printf(“%d”,~b);
返回0;
}

> > P> > C++中的~运算符是位非算子。它也被称为按位补码。这是翻转有符号整数的位

例如,如果你有

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

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

对于整数中的每个二进制数,按位NOT操作将所有1变为0,所有0变为1

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

将32位整数设置为该值,这意味着它现在为:

0000 0000 0000 1111111111111111111111

那你就不是了,这意味着:

11111111111111111000000


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

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

相同,它正在进行位补码,此输出可能有助于您更好地了解发生了什么:

std::cout <<  std::hex << " b: " << std::setfill('0') << std::setw(8) <<  b
           << " ~b: " <<  (~b) << " -65536: " << -65536 << std::endl ;
因此,我们将低16位设置为
1
,这给了我们
0000ffff
,然后我们做一个补码,将低16位设置为
0
,将高16位设置为
1
,这给了我们
ffff0000
,这等于十进制的
-65536


在本例中,由于我们使用的是逐位运算,因此在十六进制中检查数据可以让我们了解发生了什么。

假设使用32位整数

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

顶部位现在已设置。假设,这意味着我们有一个负数。反转其他位,然后添加一位,得到
0x00010000
65536

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

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

0x0000ffff
按位求反清除这些位并设置高16位:

0xffff0000
将其解释为负数将给出值
-65536

通常,在处理按位算术时,您会希望使用无符号类型,以避免这种混淆。

您的评论:

如果不是“b”。。那么输出应该是0,但为什么是-65536

表明您期待以下结果:

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

这对于逻辑not操作是正确的,例如:

uint32_t x = 0xFFFF;
uint32_t y = !x;
…但
运算符
不是逻辑not,而是按位not。这有很大的区别

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

但按位不反转给定值中的每一位。因此,二进制文件不是
0xF

0x0F:  00000000 11111111
~0x0F: 11111111 00000000

不是零,而是0xF0。

所以您已经确切地知道它的作用是什么,您的问题是什么than@suspectus请不要将C标签添加到C++标签中的问题,反之亦然。这些是不同的语言。如果你相信一个问题是C而不是C++,而且错误地标记为C++,那么在添加C标签时,应该删除C++标签。那么输出应该是0,但为什么-65536您的整数是有符号整数而不是无符号整数我想您是假设
运算符
是逻辑
运算。它实际上是一个二进制
而不是
操作。差别很大。~b=0111,仅当int为4位时。它很可能是二进制的1111110111,假设是32位integerRight,但他没有提供任何关于体系结构的信息
0x0F:  00000000 11111111
~0x0F: 11111111 00000000