这是我到目前为止所做的工作:
2^32 = 10...0
减 1 -> 01...1 得到 32 个 1
1 = 01
翻转位 -> 11....10 加 1-> 1...1 这给了你 32 个 1
我错过了什么吗?我问是因为我尝试了一个练习题,你必须翻转一个数字的所有二进制位。与 -1 进行异或运算不起作用,但与 2^32 - 1 进行异或运算可以。
这是我到目前为止所做的工作:
2^32 = 10...0
减 1 -> 01...1 得到 32 个 1
1 = 01
翻转位 -> 11....10 加 1-> 1...1 这给了你 32 个 1
我错过了什么吗?我问是因为我尝试了一个练习题,你必须翻转一个数字的所有二进制位。与 -1 进行异或运算不起作用,但与 2^32 - 1 进行异或运算可以。
32 位 2 的补码只能表示(含)范围 -(2^31)..(2^31)-1 中的值。由于 2^32-1 不在该范围内,因此可以推断您为它提出的任何位模式实际上都对应于.
让我们为 int 的 32 位数字编号,从 0 到 31。数字 #0 代表 2⁰,数字 #1 代表 2¹,等等。更一般地,数字 #n 代表 2ⁿ。
但是我们只有到 #31 的数字:我们有 32 位数字,但我们从0开始计数。没有第 32 位数字可以创建 2³²。
那么电脑有什么作用呢?它基本上假装您写了 2³²,但随后删除了除前 32 位数字(数字 0-31)之外的所有数字。这称为整数溢出。这意味着 2³²,“应该”是 1 后跟 32 个 0,实际上只是 32 个 0——当然,等于 0。从中减去 1,得到 -1。
如果您使用的是长整数(不是整数),那么您可以使用 64 位而不是 32 位。在这种情况下,第 32 位不会发生溢出,您会发现 2³² - 1 不等于-1:它等于 4294967295,就像你所期望的那样。但在这种情况下,出于类似的原因,2⁶⁴ 为 0。
要创建 2 的补码形式的任意数字,您需要翻转位并加 1。
所以对于 -1 它是以下
1 = 00000000000000000000000000000001
flip those bits
11111111111111111111111111111110
add 1 to it and you get
11111111111111111111111111111111
现在为什么是-1?
那么-1 + 1 = 0。
如果将以下内容加在一起,您将得到
11111111111111111111111111111111
+00000000000000000000000000000001
你继续做一点进位到左边的下一个位置,最终溢出字段,你还剩下 0。
00000000000000000000000000000000