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!!