C# 内存中的int32存储

C# 内存中的int32存储,c#,memory,bit,int32,C#,Memory,Bit,Int32,我有一个关于int32存储(c#)的问题 32位表示int的最大值为2^32 2^32=4294967296,如果将其除以2,则得到int32的最大值: 4294967296 / 2 = -2147483648 to 2147483648 所以我认为一半是负数,另一半是正数。 但这不可能是真的,因为2^16=65536 现在我的问题: 这实际上是如何在内存中设置的 我真的很好奇你的答案。只有一个位用于符号(负数或正数) Int32值以31位表示,第32位为单位 用作符号位。正值通过使用 符号和

我有一个关于
int32存储(c#)
的问题

32位表示int的最大值为2^32

2^32=4294967296
,如果将其除以2,则得到int32的最大值:

4294967296 / 2 = -2147483648 to 2147483648
所以我认为一半是负数,另一半是正数。 但这不可能是真的,因为
2^16=65536

现在我的问题:

这实际上是如何在内存中设置的


我真的很好奇你的答案。

只有一个位用于符号(负数或正数)

Int32值以31位表示,第32位为单位 用作符号位。正值通过使用 符号和大小表示法。负值是二的 补语表示

我找到了一篇很好的文章来理解两者的互补性

从两个补码的转换

以数字
0xFFFFFFFF
为例。在二进制中,即:

1111 1111 1111 1111 1111 1111 1111 1111
关于这个数字我们能说些什么?它的第一位(最左边)是1,这意味着它代表一个负数。这就是二的补码:前导1表示数字为负,前导0表示数字为0或正

要知道这个数字是负数,我们把这个数字的符号颠倒过来。但如何做到这一点呢?要反转符号,您只需将位反转(0变为1,1变为0)并在结果数字上加一

显然,二进制数的倒数是:

0000 0000 0000 0000 0000 0000 0000 0000
然后我们加一个

0000 0000 0000 0000 0000 0000 0000 0001
因此
0xffffff
的负数是
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如何使用2的补码执行减法

CPU使用两个负数补码的加法执行减法。让我们以8位数字为例。我们想从7中减去4

7 = 00000111
4 = 00000100
四的二补 步骤1通过将0转换为1和1转换为0,取00000100的倒数

00000100 -> 11111011
步骤2:将一个添加到反向

11111011
00000001
========
11111100
7-4=7+(4的两个补码)


这是一个很好的问题。。但普雷修斯是对的。基本上,由于整数可以保存负值,因此必须使用其内存中的一个位来允许-1和1同时存在(例如),这一点以前就出现过。符号只需要一位,因此实际数字的表示还剩下31位。范围是
-(2^31)
2^31-1
谢谢你的回答。但这为什么如此“复杂”?既然有符号位,为什么不能是这样:值2=0000 0010值-2=1000 0000 0010我想这不可能是因为编译器计算位值的方式,对吗?这里解释得很好,检查我更新的答案,我添加了一个示例,演示CPU如何使用2的补码执行加法减法。
11111011
00000001
========
11111100
00000111 (binary representation of 7)
11111100 (binary representation after Two's complement of 4)
========
00000011  (binary representation of 3)