Math.abs(~2018),掌握規律!
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!!
Math.abs(~2018),掌握規律!