为什么 printf("%d", ~0) 输出 -1?

Why does printf("%d", ~0) output -1?

为什么 printf("%d", ~0); 会产生 -1 的值?不应该是 1 因为 ~ 运算符将每个 1 位转换为 0 位,反之亦然?

据我了解,0000 将取反为 1111

~ 是按位补码运算符。 00000000 翻转为 11111111

如果你对 1(00000001)2's 的补码,你得到的是 11111111,它用二进制表示 -1

因此输出为-1

试着看看它的十六进制部分。

printf("%x", ~0);

它将打印 ffff,这意味着它对每一位取反,因此 0000000000000000 被转换为 1111111111111111。 按照逻辑,如果第一位为 1,则将其视为负数。 因此 -1.

%d takes signed integer

different variations of same input

 Signed Value ~0 -1
UnSigned Value ~0 4294967295
Hex  Value ~0 ffffffff
Hex  Value ~0 FFFFFFFF

如您所见,已设置有符号位,它只是 2 对 1 的补码

通常

-ve of n = (~n) + 1;
      complement of 5  is  -6 
 and  complement(5)+1  is   -5

在C/C++中,~是位补运算符。对于任何给定的可按位补码对象 x,它将翻转在 x 的原始表示中找到的所有二进制数字。因此,如果整数 x 用二进制表示为 0b00000000,它将变为 0x11111111

但是!!!!!

答案是总是-1。实际情况是,存在两种表示负数的方法,即一个补码和两个补码。

补码

对于任何数字x-x表示为x的按位补码。

补码

对于任何数字x-x表示为x的按位补码。

现实世界

给我找一个使用补语的(现代)系统,我给你一个免费的 cookie!事实上,一个人的补码允许像 -0 这样的废话,事实上,你的代码会在一个人的补码机器上呈现它。

BTW,正如其他答案已经发布的那样,实际的 printingnot internal一个数字的表示形式)可能会有所不同(unsigneds 只是忽略额外的最高位,因此在溢出之前允许两倍的范围)。

在32位机器中0表示为

00000000000000000000000000000000

当你应用 biwise NOT(~) 然后它翻转所有位然后位表示像 be

11111111111111111111111111111111 

这是-1 2s补码的表示。