每次看到移位運算符的時候,腦子都會懵一會兒。原因還是沒有什么理解位移運算。今天好好學習梳理下相關的知識點。
1: << 運算符-左移運算符
“<<”運算符執行左移位運算。在移位運算過程中,符號位始終保持不變。如果右側空出位置,則自動填充為 0;超出 32 位的值,則自動丟棄。
console.log(5 << 2); //返回值20
2: >> 運算符-右移運算符
與左移運算符的移動方向相反,它把 32 位數字中的所有有效位整體右移,再使用符號位的值填充空位。移動過程中超出的值將被丟棄。
console.log(1000 >> 8); //返回值3
我們看看符號為1的情況,就是負數的情況。
console.log(-1000 >> 8); //返回值 -4
如圖所示。當符號位值為 1 時,則有效位左側的空位全部使用 1 進行填充。
這里需要補充一個知識點: 負數是如何在計算機中表示的?
在計算機中,負數以原碼的補碼形式表達。
- 什么是原碼: 一個正數,按照絕對值大小轉換成的二進制數;一個負數按照絕對值大小轉換成的二進制數,然后最高位補1,稱為原碼。
比如
00000000 00000000 00000000 00000101 是 5的 原碼;
10000000 00000000 00000000 00000101 是 -5的 原碼。
- 什么是反碼:
正數的反碼與原碼相同,負數的反碼為對該數的原碼除符號位外各位取反。(取反操作指:原為1,得0;原為0,得1。(1變0; 0變1))
例如:
正數00000000 00000000 00000000 00000101 的反碼還是 00000000 00000000 00000000 00000101 ;
負數10000000 00000000 00000000 00000101每一位取反(除符號位),得11111111 11111111 11111111 11111010。
-
什么是補碼:
-
正數的補碼與原碼相同
-
負數的補碼為對該數的原碼除符號位外各位取反,然后在最后一位加1.
例如:
10000000 00000000 00000000 00000101 的反碼是:
11111111 11111111 11111111 11111010。
那么,補碼為:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
所以-5 在計算機中表達為:11111111 11111111 11111111 11111011。轉換為十六進制:0xFFFFFFFB。
- 整數 -1在計算機中是如何表達的
1: 先取-1的原碼:10000000 00000000 00000000 00000001
2: 得反碼: 11111111 11111111 11111111 11111110(除符號位按位取反)
3: 得補碼: 11111111 11111111 11111111 11111111
可見,-1在計算機里用二進制表達就是全1。16進制為:0xFFFFFF
-
總結
-
正數的反碼和補碼都與原碼相同。
-
負數的反碼為對該數的原碼除符號位外各位取反。
-
負數的補碼為對該數的原碼除符號位外各位取反,然后在最后一位加1
負數怎么轉換為 10進制?
最高位如果為1代表為負數,求值的時候,需要先把二進制的值按位取反,然后 + 1 ,得到負數絕對值的二進制碼,然后轉換為 10進制,加上負號即可。
>>> 運算符:
“>>>”運算符執行無符號右移位運算。它把無符號的 32 位整數所有數位整體右移。對於無符號數或正數右移運算,無符號右移與有符號右移運算的結果是相同的。
console.log(1000 >> 8); //返回值3
console.log(1000 >> 8); //返回值3
對於負數來說,無符號右移將使用 0 來填充所有的空位,同時會把負數作為正數來處理
console.log(-1000 >> 8); //返回值 -4
console.log(-1000 >>> 8); //返回值 16777212