Math.abs(~2018),掌握规律!

时间:2024-07-05 15:05:50

Math.abs(~2018)

  这要用到一些计算机的基础知识。

Math.abs(x)指的是返回一个数的绝对值,而关键在“~2018”,这是取反操作符,故取相反数得结果为-2018,Math.abs(-2018) 即2018,大功告成?结果,输入发现,错误!为什么?

  首先,取反操作是按位取反,而不是取相反数,即把数据的二进制数中0变1,1变0;

  然后,要考虑到计算机中数据的存储是二进制数据,以补码的形式存在;

此处,我们要把2018转化为二进制数,然后取反之后在转化为十进制数吗?显然这对于2018这么大的数很麻烦,不如我们分析下有什么规律可循。

举个栗子:

var x = 10;

在计算机中一个整型数4字节,1字节8位,所以数字10在计算机中存储占32位,即

00000000 00000000 00000000 00001010,

按位取反,得

11111111 11111111 11111111 11110101,

这个二进制数据就是“~10”,最高位是1表示它是个负数,那么我们如何转化为十制数呢?

这里又涉及到了负数在计算机里的存储问题,计算机里,负数以其正值的补码形式存在。

再举个例子:

-10 ,二进制表示为

10000000 00000000 00000000 00001010

原码,取其绝对值也就是10,即

00000000 00000000 00000000 00001010

反码,按位取反,得

11111111 11111111 11111111 11110101

补码,即将反码加1,得

11111111 11111111 11111111 11110110

至此,我们得到了计算机中-10的二进制存储形式。

然后我们再回到上一个问题,我们怎么根据计算机中的补码得到这个负数呢?

我们可以按原路返回,就是将计算机中存储的二进制补码减1,然后取反,再得到原码,换成相应负数即可,不过这样有点麻烦,因为涉及到了减法操作。

另一种方法,将负数的补码先取反,然后加1,最高位置换为1即可。

对于~10,在计算机中存储为

11111111 11111111 11111111 11110101   (这是10取反的结果,但却是未知数X的补码形式)

先取反,得

00000000 00000000 00000000 00001010   (此处,再次取反,返回10)

再加1,得

00000000 00000000 00000000 00001011   (10+1得11)

最高位变1,即

10000000 00000000 00000000 00001011   (取相反数即-11)

结果是“-11”

由此我们可以看出规律:“~x”的结果为“-(x+1)”

所以“~2018”就等于“-2019”,Math.abs(-2019)即2019!!