JS按位非(~)运算符补充

236 阅读2分钟

#计算机中的有符号数都是以二进制的补码形式存储的

原码和补码的关系,区分正数和负数

对于正数:原码 = 反码 = 补码。
对于负数:

  • 反码为原码的最高位不变,其余位取反。
  • 补码为在反码的基础上加1。
  • 负数:补码(x) = -x - 1,正数:补码(x) = x

对于~[运算符]其实就是按位取反的意思,操作的是二进制数。

例如:2进行~2操作后的步骤为:

  1. 2的二进制为: 00000010(原码,反码,补码一致,这里使用的其实也是补码)
  2. ~2 按位取反后为(补码取反):11111101。(这里是所有的位置都取反,包括符号位,取反后得到的还是原码,根据符号位判断正数还是负数,正数为0,负数为1)
  3. 由于计算机中所有有符号数都是以补码的形式存在,所有进行转换。
  4. 11111101的反码为10000010(负数的符号位不变)
  5. 10000010的补码为10000011 (反码+1=补码)
  6. 1000011对应十进制为-3(-(12^1+12^0)=-(2+1))

例如:-2进行~-2操作后的步骤为:

  1. -2的二进制反码: 10000010(-2原码)-> 11111101(-2反码,符号位不变,其他取反) -> 11111110( 获取-2补码)
  2. ~-2 按位取反后为:00000001
  3. 符号位是0,最后的补码不变(正数的原码,反码,补码一致): 00000001

**总上,2=-3,-2 === 1,无论正数负数,都是先获取数字的补码,然后再运算,正数的原码,反码,补码一致,所以~按位取反之后获取取反后的原码进行补码换算即可。负数的情况也是要先获取负数的补码,再按位取反补码,由于负数按位取反之后,符号位是0,所以获取负数原码,然后计算出补码,按位取反,得到新的原码,关键就在按位取反之后的符号位是0还是1,是0就可以直接获取对应补码,得到十进制数,是1的话,就要根据负数的规则换算补码,然后得到十进制值