编译器如何将打印 unsigned int 视为有符号 int?
How does the compiler treats printing unsigned int as signed int?
我想弄清楚为什么会出现以下代码:
{
unsigned int a = 10;
a = ~a;
printf("%d\n", a);
}
a
一开始会是00001010
,NOT运算后会变成
进入11110101
.
当一个人试图将 a
打印为有符号整数时究竟发生了什么,这使得
打印出来的结果是-11
?
我想我最终可能会看到 -5
(根据二进制表示),但不会看到 -11
。
我很高兴得到有关此事的澄清。
2的补码用于存储负数。
数字 10 在 4 字节二进制中是 0000 0000 0000 0000 0000 0000 0000 1010。
a=~a使a的内容为1111 1111 1111 1111 1111 1111 1111 0101.
当这个数字被视为有符号整数时,它会告诉编译器
取最高位为符号,其余为幅值。
msb中的1使数字成为负数。
因此对剩余的位进行2的补码运算
这样111 1111 1111 1111 1111 1111 1111 0101就变成了
000 0000 0000 0000 0000 0000 0000 1011。
这在解释为十进制整数时变为 -11。
当你写 a = ~a;
时,你会反转 a 中的每一位,也称为 1 的补码。
负数的表示被声明为实现依赖,这意味着不同的体系结构可能对-10
或-11
有不同的表示。
假设通用处理器上的 32 位体系结构使用 2 的补码表示负数 -1 将表示为 FFFFFFFF(十六进制)或 32 位到 1。
~a
将表示为 = FFFFFFF5
或二进制 1...10101
表示 -11.
注意:第一部分始终相同且不依赖于实现,~a
在任何 32 位架构上都是 FFFFFFF5
。只有第二部分 (-11 == FFFFFFF5
) 是依赖于实现的。顺便说一句,在使用 1 的补码来表示负数的架构上,它将是 -10。
我想弄清楚为什么会出现以下代码:
{
unsigned int a = 10;
a = ~a;
printf("%d\n", a);
}
a
一开始会是00001010
,NOT运算后会变成
进入11110101
.
当一个人试图将 a
打印为有符号整数时究竟发生了什么,这使得
打印出来的结果是-11
?
我想我最终可能会看到 -5
(根据二进制表示),但不会看到 -11
。
我很高兴得到有关此事的澄清。
2的补码用于存储负数。
数字 10 在 4 字节二进制中是 0000 0000 0000 0000 0000 0000 0000 1010。
a=~a使a的内容为1111 1111 1111 1111 1111 1111 1111 0101.
当这个数字被视为有符号整数时,它会告诉编译器 取最高位为符号,其余为幅值。
msb中的1使数字成为负数。
因此对剩余的位进行2的补码运算
这样111 1111 1111 1111 1111 1111 1111 0101就变成了 000 0000 0000 0000 0000 0000 0000 1011。
这在解释为十进制整数时变为 -11。
当你写 a = ~a;
时,你会反转 a 中的每一位,也称为 1 的补码。
负数的表示被声明为实现依赖,这意味着不同的体系结构可能对-10
或-11
有不同的表示。
假设通用处理器上的 32 位体系结构使用 2 的补码表示负数 -1 将表示为 FFFFFFFF(十六进制)或 32 位到 1。
~a
将表示为 = FFFFFFF5
或二进制 1...10101
表示 -11.
注意:第一部分始终相同且不依赖于实现,~a
在任何 32 位架构上都是 FFFFFFF5
。只有第二部分 (-11 == FFFFFFF5
) 是依赖于实现的。顺便说一句,在使用 1 的补码来表示负数的架构上,它将是 -10。