编译器如何将unsigned int打印为signed int?

时间:2015-08-02 18:08:05

标签: c printing unsigned-integer

我试图找出以下代码的原因:

{
  unsigned int a = 10;
  a = ~a;
  printf("%d\n", a);
}

a将以00001010开头,并且在NOT opertaion之后,将会转换

进入11110101

当试图将a打印为有符号整数时,会发生什么?

打印结果为-11

我以为我最终会看到-5(根据二进制表示),但不是-11

我很乐意澄清这件事。

2 个答案:

答案 0 :(得分:6)

2'补码表示法用于存储负数。

数字10是0000 0000 0000 0000 0000 0000 0000 1010,以4字节为二进制。

a = ~a使得a的内容为1111 1111 1111 1111 1111 1111 1111 0101。

当被视为signed int时,此数字将告诉编译器 把最重要的一点作为符号并作为幅度休息。

msb中的1表示数字为负数。

因此,对剩余的位执行2的补码操作。

因此111 1111 1111 1111 1111 1111 1111 0101成为 000 0000 0000 0000 0000 0000 0000 1011.

当解释为十进制整数时,它变为-11。

答案 1 :(得分:2)

当你写a = ~a;时,你反转a中的每一位,也称为1的补充。

负数的表示形式声明为依赖于实现,这意味着不同的体系结构可能具有-10-11的不同表示形式。

假设公共处理器上的32架构使用补码2表示负数-1将表示为FFFFFFFF(十六进制)或32位表示为1.

~a将表示为= FFFFFFF5或二进制1...10101,表示-11。

Nota:第一部分始终相同且不依赖于实现,~a 在任何32位架构上都是 FFFFFFF5。它只是依赖于实现的第二部分(-11 == FFFFFFF5)。顺便说一句,在一个架构中它将是-10,它将使用补码1来表示负数。