淺析java移位符的具體使用
概述
java移位符主要包括3種:
運算符 | 名稱 |
---|---|
>> | 左移運算符 |
<< | 有符號右移運算符 |
<<< | 無符號右移運算符 |
這里我們先附上代碼運行實例,原理將在后面以解析下面代碼的方式進行講解:
public class BitOperatorTest { public static void main(String[] args){ System.out.println(1 << 4); System.out.println(-1 << 3); System.out.println(8 >> 3); System.out.println(-8 >> 3); System.out.println(-8 >>> 3); } }
結(jié)果如下:
16
-8
1
-1
536870911
首先我們需要清楚在計算機系統(tǒng)中,數(shù)值一般用補碼來表示,主要原因是因為使用補碼可以使符號位和其他位統(tǒng)一處理,我們需要將上面的數(shù)值都轉(zhuǎn)化為補碼。
左移運算符
1 << 4
首先我們將1化為源碼:0000 0000 0000 0000 0000 0000 0000 0001 (因為其是int類型,所以化為二進制有32位)
正數(shù)的補碼和反碼等于源碼的本身。所以補碼也為上述二進制代碼。
左移運算符是將操作數(shù)的二進制碼整理左移指定位數(shù),左移后右面空出的位用0來補充。
左移4位 0000 0000 0000 0000 0000 0000 0000 0001 1*2^0=1
<font color=red>0000</font> 0000 0000 0000 0000 0000 0000 0001 <font color=blue>0000</font> (紅色被移除截斷,藍(lán)色是新補的0) 1*2^4=16
-1 << 3
我們開始第二個輸出語句,這是一個負(fù)數(shù)。負(fù)數(shù)的反碼是他的源碼符號位不變,其余按位取反。補碼是他的反碼加一。
所以我們可以得到-1的源碼為1000 0000 0000 0000 0000 0000 0000 0001 -1*2^0=-1
反碼為1111 1111 1111 1111 1111 1111 1111 1110
補碼為1111 1111 1111 1111 1111 1111 1111 1111
對補碼進行操作得<font color=red>111</font> 1111 1111 1111 1111 1111 1111 1111 1<font color=blue>000</font> (紅色被移除截斷,藍(lán)色是新補的0)
將結(jié)果數(shù)轉(zhuǎn)化為源碼得1000 0000 0000 0000 0000 0000 0000 1000 -1*2^3=-8
總結(jié)
所以通過上面對左移運算符的簡單使用不難發(fā)現(xiàn),我們可以將其簡便理解為移動幾位,就是為操作數(shù)乘以2的幾次方。
右移運算符
左移運算符不牽扯符號位的增補符號位,所以沒有有無符號分類
有符號右移運算符
8 >> 3
根據(jù)上面流程,我這里直接就簡化為
源碼為:0000 0000 0000 0000 0000 0000 0000 1000 1*2^3=8
反碼為:0000 0000 0000 0000 0000 0000 0000 1000
補碼為:0000 0000 0000 0000 0000 0000 0000 1000
運算后結(jié)果:<font color=blue>000</font>0 0000 0000 0000 0000 0000 0000 0001 <font color=red>000</font> 1*2^0=1(紅色被移除截斷,藍(lán)色是新補的符號位,并且以原來的符號位填補)
-8 >> 3
根據(jù)上面流程,我這里直接就簡化為
源碼為:1000 0000 0000 0000 0000 0000 0000 1000 -1*2^3=8
反碼為:1111 1111 1111 1111 1111 1111 1111 0111
補碼為:1111 1111 1111 1111 1111 1111 1111 1000
運算后結(jié)果:<font color=blue>111</font>1 1111 1111 1111 1111 1111 1111 1111 <font color=red>000</font> (紅色被移除截斷,藍(lán)色是新補的符號位,并且以原來的符號位填補)
轉(zhuǎn)換為源碼為:1000 0000 0000 0000 0000 0000 0000 0001 -1*2^0=-1
總結(jié)
同左移運算符一樣,總結(jié)規(guī)律后可得出,右移運算符移動幾位則是對操作數(shù)除以2的多少次方。
無符號右移運算符
-8 >>> 3
根據(jù)上面流程,我這里直接就簡化為
源碼為:1000 0000 0000 0000 0000 0000 0000 1000 -1*2^3=8
反碼為:1111 1111 1111 1111 1111 1111 1111 0111
補碼為:1111 1111 1111 1111 1111 1111 1111 1000
運算后結(jié)果:<font color=yellow>000</font>1 1111 1111 1111 1111 1111 1111 1111 <font color=red>000</font> (紅色被移除截斷,注意黃色部分,在無符號右移運算位中統(tǒng)一補0)
此時數(shù)值將會非常大,所以得到程序中的結(jié)果。
補充
如果操作類型低于int類型,比如byte,char等,先將其轉(zhuǎn)化為int類型在進行移位。
對于int類型的移位,如果移動位數(shù)超過32位,則讓位數(shù)對32取余,然后進行運行,即a>>33 == a>>1 a>>32 ==a
同樣如果對于long類型的移位,移動位數(shù)超過64,則也需要對移動位數(shù)進行處理。
代碼補充
對于補充內(nèi)容的代碼不進行詳解,代碼及運算結(jié)果如下,基本流程與上面類似,
代碼:
public class BitOperatorTest { public static void main(String[] args){ System.out.println((char)4 << 4); System.out.println(4 << 4); System.out.println(4 << 36); System.out.println((long)1214 >> 66); System.out.println((long)1214 >> 2); } }
運行結(jié)果:
64
64
64
303
303
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis學(xué)習(xí)筆記(二)之關(guān)聯(lián)關(guān)系
這篇文章主要介紹了MyBatis學(xué)習(xí)筆記(二)之關(guān)聯(lián)關(guān)系 的相關(guān)資料,需要的朋友可以參考下2016-02-02使用Java代碼進行因數(shù)分解和求最小公倍數(shù)的示例
這篇文章主要介紹了使用Java代碼進行因數(shù)分解和求最小公倍數(shù)的示例,都是基于最基礎(chǔ)的算法原理實現(xiàn),需要的朋友可以參考下2015-11-11Spring Boot 2.0多數(shù)據(jù)源配置方法實例詳解
這篇文章主要介紹了Spring Boot 2.0多數(shù)據(jù)源配置方法實例詳解,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-09-09SpringBoot如何統(tǒng)一清理數(shù)據(jù)
這篇文章主要介紹了SpringBoot如何統(tǒng)一清理數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01深入探究Java?@MapperScan實現(xiàn)原理
之前是直接在Mapper類上面添加注解@Mapper,這種方式要求每一個mapper類都需要添加此注解,麻煩。通過使用@MapperScan可以指定要掃描的Mapper類的包的路徑,這篇文章深入探究Java?@MapperScan的實現(xiàn)原理2023-01-01