⛽️第5期第3题:按位取反,为什么`~2 = -3`?
Opened this issue · 0 comments
按位取反,为什么~2 = -3
?
接下来,分享一道与JavaScript
原生无关的题目吧,主要也是看到群里有小伙伴问了关于按位取反~
的用法,这边统一科普一下,😁。
正常一个数字,例如1
和2
,或者-1
和-2
。
如果我们对它们进行按位取反的话,结果会是这样:
~1 = -2
~2 = -3
~-1 = 0
~-2 = 1
看不懂没关系,让我们来一步步看看实现的过程哈。
在这里其实是分了正数和负数的,因为符号不同取反的过程也会不同。
1.1 正数按位取反
先让我们来看看正数的按位取反。
比如先看看~1 = -2
,过程如下:
1. 十进制转为二进制原码
首先将十进制的1
转化为二进制原码为:0000 0001
2. 二进制原码按位取反
之后将原码按位取反:
也就是将0000 0001
=> 1111 1110
(取反应该知道啥意思吧?就是0
换成1
,1
换成0
)
3. 取反后的二进制转为原码
再将取反后的二进制码转为原码二进制:
也就是将1111 1110
=> 1000 0010
这里你估计看着都点懵了,当我们将取反后的二进制转为原码二进制的时候,其实是有以下两步的:
- 需要判断取反后的二进制的第一个位是不是
1
,这个第一位我们称之为符号位,如果是1
的话就表示即将要转成的数是一个负数,如果是0
的话表示即将要转的数是一个正数,这个符号位是不能动的;在这里我们可以看到1111 1110
的第一位是1
,所以表示即将要转的数是一个负数,同时我们不动它。 - 然后将除了第一位以外其它位数取反并
+1
。所以会有这么两个过程:1111 1110
=>1000 0001
1000 0001
=>1000 0010
(这步是对上一步的结果+1
,因为上一步的最后一个数是1
,所以它再加上1
就需要向前进一位了,因此变成了1000 0010
)
4. 将原码二进制转为十进制
最后一步就是将我们前面得到的1000 0010
这个二进制转化为十进制了。
第一位符号位,是1
,则表示是个负数,所以结果为-2
。
OK👌,搞懂了这个步骤之后再让我们自己来转换一下~2 = -3
吧:
1. 0000 0010
2. 1111 1101
3. 1000 0011
4. -3
正数按位取反总结
- 十进制转为二进制原码
- 二进制原码按位取反
- 符号位保留,其余位取反+1
- 二进制原码转为十进制
1.2 负数按位取反
负数的按位取反和上面就有些不一样了,主要是第二步和第三步调换一下顺序:
- 十进制转为二进制原码
- 符号位保留,其余位取反+1
- 二进制原码按位取反
- 二进制原码转为十进制
例如:~-1 =0
的转换过程:
1. 十进制转为二进制原码
这步和正数按位取反是一样的:
-1
=> 1000 0001
2. 符号位保留,其余位取反+1
转换过程:
1000 0001
=>1111 1110
(取反)1111 1110
=>1111 1111
(取反后 + 1)
3. 二进制原码按位取反
将刚刚得到的再进行按位取反:
1111 1111
=> 0000 0000
4. 二进制原码转为十进制
0000 0000
=> 0
OK👌,现在自己来转换一下~-2 = 1
吧:
1. 1000 0010
2. 1111 1110
3. 0000 0001
4. 1
这里没啥诀窍,关键就是要记住转换的过程然后不断的练习吧 😂。
另外关于~~
的用法还可以看呆呆的另一篇文章哟《JS中按位取反运算符~及其它运算符》