Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⛽️第5期第3题:按位取反,为什么~2 = -3? #32

Open
LinDaiDai opened this issue Jun 23, 2020 · 0 comments
Open

⛽️第5期第3题:按位取反,为什么~2 = -3? #32

LinDaiDai opened this issue Jun 23, 2020 · 0 comments

Comments

@LinDaiDai
Copy link
Owner

LinDaiDai commented Jun 23, 2020

按位取反,为什么~2 = -3?

接下来,分享一道与JavaScript原生无关的题目吧,主要也是看到群里有小伙伴问了关于按位取反~的用法,这边统一科普一下,😁。

正常一个数字,例如12,或者-1-2

如果我们对它们进行按位取反的话,结果会是这样:

  • ~1 = -2
  • ~2 = -3
  • ~-1 = 0
  • ~-2 = 1

看不懂没关系,让我们来一步步看看实现的过程哈。

在这里其实是分了正数和负数的,因为符号不同取反的过程也会不同。

1.1 正数按位取反

先让我们来看看正数的按位取反。

比如先看看~1 = -2,过程如下:

1. 十进制转为二进制原码

首先将十进制的1转化为二进制原码为:0000 0001

2. 二进制原码按位取反

之后将原码按位取反:

也就是将0000 0001 => 1111 1110

(取反应该知道啥意思吧?就是0换成11换成0)

3. 取反后的二进制转为原码

再将取反后的二进制码转为原码二进制:

也就是将1111 1110 => 1000 0010

这里你估计看着都点懵了,当我们将取反后的二进制转为原码二进制的时候,其实是有以下两步的:

  1. 需要判断取反后的二进制的第一个位是不是1,这个第一位我们称之为符号位,如果是1的话就表示即将要转成的数是一个负数,如果是0的话表示即将要转的数是一个正数,这个符号位是不能动的;在这里我们可以看到1111 1110的第一位是1,所以表示即将要转的数是一个负数,同时我们不动它。
  2. 然后将除了第一位以外其它位数取反并+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. 十进制转为二进制原码
  2. 二进制原码按位取反
  3. 符号位保留,其余位取反+1
  4. 二进制原码转为十进制

1.2 负数按位取反

负数的按位取反和上面就有些不一样了,主要是第二步和第三步调换一下顺序:

  1. 十进制转为二进制原码
  2. 符号位保留,其余位取反+1
  3. 二进制原码按位取反
  4. 二进制原码转为十进制

例如:~-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中按位取反运算符~及其它运算符》

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant