Math.abs(~2018)前端
某前端群的入门问题长姿式了,一个简单的入门问题却引起了个人思考,深深的体会到本身在学习前端技术的同时忽略遗忘了一些计算机的基础知识。学习
对于 JS Math对象没什么可说的, Math.abs(x)指的是返回一个数的绝对值,而解题关键在“~2018”,乍一看,这是什么意思,不会是“-2018”符号打错了吧?细思一下才恍然大悟,这是取反操做符,故取相反数得结果为-2018,Math.abs(-2018) 即2018,大功告成!但是,输入进去发现,What!错误!Why!对象
首先,取反操做是按位取反,而不是取相反数,即把数据的二进制数中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!!