这是我到目前为止完成的工作:
2 ^ 32 = 10 ... 0
减去1-> 01 ... 1 那给你32个1
1 = 01
翻转位-> 11 .... 10 加1-> 1 ... 1 那给你32个1
我想念什么吗?我问是因为我尝试了一种练习problem,在这种练习中,您必须翻转数字的所有二进制位。与-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位)之外的所有数字。这称为integer overflow。这意味着2³²(应为1,后跟32 0)实际上只有32 0(当然等于0)。减去1,得到-1。
如果您使用long(而不是ints),则可以使用64位而不是32位。在这种情况下,在32位不会发生溢出,并且您会发现2³²-1不会't等于-1:等于4294967295,就像您期望的那样。但是在这种情况下,出于类似原因,2⁶⁴为0。
,要以2的补码形式创建任意数字,请翻转这些位并添加1。
所以对于-1来说是以下
PASS src/stackoverflow/59416347/users.test.js (9.166s)
59416347
✓ should return all the users (18ms)
console.log src/stackoverflow/59416347/users.test.js:41
{ data: { result: { success: true,payload: [Array] } } }
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 90.91 | 100 | 83.33 | 90.91 | |
users.js | 90.91 | 100 | 83.33 | 90.91 | 12 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed,1 total
Tests: 1 passed,1 total
Snapshots: 0 total
Time: 10.518s
现在为什么是-1?
-1 +1 = 0。
如果将以下各项加在一起,您将获得
1 = 00000000000000000000000000000001
flip those bits
11111111111111111111111111111110
add 1 to it and you get
11111111111111111111111111111111
您继续往左移一点,最终导致场地溢出,剩下0。
11111111111111111111111111111111
+00000000000000000000000000000001