我是C的新手,所以我对这段代码感到困惑。我想知道一个整数的补码是如何工作的
代码:
int f = 45;
printf("Value of %d is = %d",f,~f);
现在输出为
"45的值=-46"
我的问题是:这是一个整型变量,在我的编译器中,int是4个字节,即。2^32
这意味着它将在机器中表示为
4294967296 . . . . . . . 32 16 8 4 2 1
0 1 0 1 1 0 1
对吗?或者它将被表示到前8位?
如果表示到32位,那么在'32'位和'4294967296'之间的数字将是0,因为这是4字节的整数,需要这样表示,对吗?
那么数字的表示呢,我需要一些参考点。我会自己研究,假设int是4个字节,如果我写int a = 3;它是用8位表示0000000000000000000000000000000000000011来表示,如果我写int a = 257,它是用0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
然后,当我们要计算~1s补码时,我们要反转位的值,因此在这种情况下,32和4294967296之间的位将从0变为1?如果是这样,那么它将成为一些大的价值?这-46是怎么计算出来的?
3条答案
按热度按时间a0x5cqrl1#
正如你所说,
~f
导致f
的"one's complement"值,即查看二进制表示,~f
将翻转f
的所有位。因此,~
通常被称为“按位非”运算符。在int
为32位的系统上,该类型的所有值都使用完整的32位表示,而不管值是什么。因此,例如“3”表示为00000000 00000000 00000000 00000011
,因此“~3”表示为11111111 11111111 11111111 11111100
。您的计算机,像大多数现代计算机一样,不使用“一的补数”来表示负整数。它使用"two's complement"代替。因此,当打印
~f
的值时,它将打印~f
的位模式以“二进制补码”表示的值,而不是“一进制补码”。规则很简单。如果
f
是一个正整数,那么在“二进制补码”中:或者,等价地:
因此,在这种情况下,当
f
= 45时,我们得到~f
= -(45+1)=-46。p1tboqfb2#
用十六进制打印结果可能会给你给予一些关于补码的概念
将产生以下产出:在十六进制记数法中,每个数字的1-补码应该加起来为15(0xF),如本例所示。
qlzsbp2j3#
关于数字的表示,我需要一些参考点,然后我会自己研究,假设int是4字节,如果我写int a = 3;它是用8位表示0000000000000000000000000000000000000011来表示,如果我写int a = 257,它是用0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
257不能存储在8位中,所以它将是
00000001
。所以你的逻辑是错误的,因为8位字节不能神奇地变成16位。更复杂的是,32位的数字将不会被存储(在大多数系统上,因为他们使用little endian notation)的方式显示。它将是:
对于C语言中的补码运算(当使用标准运算符时),您需要将计算机更改为例如PDP-1。
您甚至可以玩Spacewars游戏!