對於位運算符一直懵懵懂懂,今天又研究一遍感覺恍然大悟,俗話說:好記性不如爛筆頭。趕緊記下來以防忘記,哈哈~
對於網上大部分說的什麼右移1相當於除以2,左移1相當於乘以2在我們思想中形成了根深蒂固的影響,然而這些解釋我並不太認可,我們要了解起本質就不會被這些困擾了。
java位運算符有三種:<< 左移 >>有符號右移 >>> 無符號右移。
在此說明一點,位運算符操作的都是二進制數,運算之前請先將十進制轉爲二進制
- <<(左移運算)
看下面例子之前,先解釋下java中的int類型是4個字節(32bit)的,32位太長我們就用1個字節(8bit)做例子
十進制 | 二進制 | 備註 | << 1 | 轉化之後的十進制 | << 2 | 轉化之後的十進制 |
---|---|---|---|---|---|---|
3 | 0000 0011(原碼) | java採用原碼錶示(正數) | 0000 0110(原碼) | 6 | 0000 1100(原碼) | 8 |
-3 | 1111 1101(補碼) | java採用補碼錶示(負數) | 1111 1010(補碼) | -6 | 1111 0100(補碼) | -8 |
如果上面的數字左移6位和左移8位呢?是不是更有點暈了,我們看例子:
十進制 | 二進制 | 備註 | <<6 | 轉化之後 | <<8 | 轉化之後 |
---|---|---|---|---|---|---|
3 | 0000 0011(原碼) | java採用原碼錶示(正數) | 1100 0000(-64對應的補碼) | 你會發現這個應該是個負數,因爲符號位爲1(沒錯,此時這個數是-64) | 0000 0011(沒有變化) | 3 |
-3 | 1111 1101(補碼) | java採用補碼錶示(負數) | 0100 0000(64對應的原碼) | 你會發現這個應該是個正數,因爲符號位爲0(沒錯,此時這個數是64) | 1111 1101(沒有變化) | -3 |
java在位移時如果>= 8bit時會取模進行位移,如果你位移8位就是 8 - 8 = 0,如果你位移9位 9-8 = 1就是這樣。明白了嗎?
2.有符號右移>>
運算規則:符號位不動,其他高位補符號位對應的數,(正數補0,負數補1),表格走起:
十進制 | 二進制 | 備註 | >>1 | 轉化之後 | >> 7 | 轉化之後 |
---|---|---|---|---|---|---|
3 | 0000 0011(原碼) | java採用原碼錶示(正數) | 0000 0001(1的原碼) | 1 | 0000 0000 | 0 |
-3 | 1111 1101(補碼) | java採用補碼錶示(負數) | 1111 1110(-2的補碼) | -2 | 1111 1111(-1補碼) | -1 |
如果右移>=8時,還是會取模運算,同左移
3.無符號位右移 >>>
運算規則:不管正負數,符號位也右移,高位都補0
十進制 | 二進制 | 備註 | >>>1 | z轉化之後 |
---|---|---|---|---|
3 | 0000 0011(原碼) | java採用原碼錶示(正數) | 0000 0001 | 1 |
-3 | 1111 1101(補碼) | java採用補碼錶示(負數) | 0111 1110 | z轉化之後變成正數了,就是因爲符號位移動,高位補0造成的 |