我有一个关于int32 storage (c#)
.
32 位意味着 int 的最大数字是 2^32。
2^32 = 4294967296
,如果你将它除以 2,你会得到 int32 的最大值:
4294967296 / 2 = -2147483648 to 2147483648
所以我认为一半的位是负数,另一个是正数。但这不可能是真的,因为2^16 = 65536
。
现在我的问题:
这实际上是如何在内存中设置的?
我真的很好奇你的答案。
只有一位用于符号(负或正)
Int32 值以 31 位表示,其中 30 秒位用作符号位。正值通过使用符号和大小表示来表示。负值是二进制补码表示,MSDN
Int32.MaxValue = 2^31 - 1 = 01111111111111111111111111111111
Int32.MinValue = -2^31 = 10000000000000000000000000000000
我在这里找到了很好的文章来理解两者的补码。
二进制补码转换
以数字0xFFFFFFFF
为例。在二进制中,即:
1111 1111 1111 1111 1111 1111 1111 1111
我们能对这个数字说些什么?它的第一个(最左边)位是 1,这意味着这表示一个负数。这就是二进制补码的方式:前导 1 表示数字为负数,前导 0 表示数字为 0 或正数。
要查看这个数字的负数,我们反转这个数字的符号。但是怎么做呢?要反转符号,您只需反转位(0 变为 1,1 变为 0)并将结果数加 1。
该二进制数的反转显然是:
0000 0000 0000 0000 0000 0000 0000 0000
然后我们添加一个。
0000 0000 0000 0000 0000 0000 0000 0001
所以0xFFFFFFFF
is的负数0x00000001
,更常被称为1
。0xFFFFFFFF
也是如此-1
。
转换为二进制补码
请注意,这是双向的。如果您有 -30,并且想用 2 的补码表示它,则采用 30 的二进制表示:
0000 0000 0000 0000 0000 0000 0001 1110
反转数字。
1111 1111 1111 1111 1111 1111 1110 0001
并添加一个。
1111 1111 1111 1111 1111 1111 1110 0010
转换回十六进制,这是0xFFFFFFE2
编辑,CPU如何使用二进制补码执行减法
CPU 使用负数的补码进行减法运算。让我们以 8 位数字为例。我们想从 7 中减去 4。
7 = 00000111
4 = 00000100
2' 补码 4
第 1 步通过将 0 转换为 1 并将 1 转换为 0 来取 00000100 的倒数
00000100 -> 11111011
步骤 2 逆加一
11111011
00000001
========
11111100
7- 4 = 7 +(4 的补码)
00000111 (binary representation of 7)
11111100 (binary representation after Two's complement of 4)
========
00000011 (binary representation of 3)