位運(yùn)算大家平時(shí)用的比較少,但是當(dāng)你看jdk源碼時(shí)發(fā)現(xiàn)會(huì)有很多位運(yùn)算冈闭。我們知道,計(jì)算機(jī)最基本的操作單元是字節(jié)(byte)遇八,一個(gè)字節(jié)由8個(gè)位(bit)組成耍休,一個(gè)位只能存儲(chǔ)一個(gè)0或1,其實(shí)也就是高低電平羊精。無論多么復(fù)雜的邏輯最終體現(xiàn)在計(jì)算機(jī)最底層都只是對(duì)01的存儲(chǔ)和運(yùn)算。java中我們使用算數(shù)操作符操作數(shù)據(jù) 1+2 實(shí)際上 jvm最終也會(huì)編譯為位運(yùn)算進(jìn)行計(jì)算喧锦,所以有一些比較復(fù)雜的運(yùn)算我們可以考慮通過位運(yùn)算來實(shí)現(xiàn),提高效率束亏,當(dāng)然在后面的文章我也會(huì)在權(quán)限系統(tǒng)中使用位運(yùn)算實(shí)現(xiàn)權(quán)限校驗(yàn)存儲(chǔ)阵具。
位運(yùn)算用來操作整數(shù)基本數(shù)據(jù)類型中的單個(gè)"比特"(bit),即二進(jìn)制位定铜。整數(shù)類型包括 long,int揣炕,short东跪,char 和 byte。位運(yùn)算在java中分為位邏輯運(yùn)算符和位移運(yùn)算符兩類越庇,再開始講解位運(yùn)算之前先和大家在復(fù)習(xí)一下10進(jìn)制于2進(jìn)制的轉(zhuǎn)化過程奉狈。
10進(jìn)制轉(zhuǎn)2進(jìn)制:
方法為:十進(jìn)制數(shù)除2取余法,即十進(jìn)制數(shù)除2仁期,余數(shù)為權(quán)位上的數(shù),得到的商值繼續(xù)除2熬的,依此步驟繼續(xù)向下運(yùn)算直到商為0為止赊级。
2進(jìn)制轉(zhuǎn)10進(jìn)制
方法為:把二進(jìn)制數(shù)按權(quán)展開、相加即得十進(jìn)制數(shù)理逊。
嗯,上述是百度經(jīng)驗(yàn)分享過來的兑徘。好接下來我們開始詳細(xì)介紹每類位運(yùn)算:
.位邏輯運(yùn)算:
位邏輯運(yùn)算符包含 4 個(gè):&(與)羡洛、|(或)挂脑、~(非)和 ^(異或)欲侮。
&(與):
位相同為1,不同位為0镀脂,看下面的demo:
public static void main(String[] args){
????????int a=129;
????????int b=128;
????????System.out.println("a 和b 與的結(jié)果是:"+(a&b));
}
運(yùn)行結(jié)果a 和b 與的結(jié)果是:128忘伞,可能有的同學(xué)覺得奇怪怎么會(huì)128了呢薄翅,別急我們分析一下這個(gè)程序:上述說道位運(yùn)算都是操作二進(jìn)制位,那么我們先把 a = 129 轉(zhuǎn)化為2進(jìn)制10000001(同學(xué)們自己跟著算一下)鼎天,b=128轉(zhuǎn)化為2進(jìn)制10000000暑竟,根據(jù)與邏輯運(yùn)算符的運(yùn)算規(guī)律斋射,只有兩個(gè)位都是1結(jié)果才是1但荤,對(duì)比后二進(jìn)制結(jié)果=10000000,換算成10進(jìn)制也就是128咯桑包!
或(|):
兩個(gè)位只要有一個(gè)1則為1,否則為0
public static void main(String[] args)
{
????????int a=129;
????????int b=128;
????????System.out.println("a 和b 或的結(jié)果是:"+(a|b));
}
運(yùn)行結(jié)果 a 和b 或的結(jié)果是:129 纺非。好我們接著來分析:
a 的值是129,轉(zhuǎn)換成二進(jìn)制就是10000001烧颖,而b 的值是128,轉(zhuǎn)換成二進(jìn)制就是10000000拆火,根據(jù)或運(yùn)算符的運(yùn)算規(guī)律涂圆,只有兩個(gè)位有一個(gè)是1榜掌,結(jié)果才是1乘综,可以知道結(jié)果就是10000001,即129卡辰。
非(~):
如果值為 0 結(jié)果為1 為1結(jié)果為0(二進(jìn)制比如 ~10000 = 01111),得到反碼后再+1得到補(bǔ)碼
public static void main(String[] args) {
????????int a = 10;
????????System.out.println("a 非的結(jié)果是:"+(~a));
}
運(yùn)行結(jié)果 a 非的結(jié)果是:-11反砌。10的2進(jìn)制是 00000000 00001010 然后我們?nèi)》创a 11111111 11110101 在+1得到補(bǔ)碼 1000000000001011萌朱,用十進(jìn)制數(shù)表示即為 -11。(二進(jìn)制最高位是1則為負(fù)數(shù)晶疼,0則為正數(shù))
異或(^)
兩個(gè)操作數(shù)中同位數(shù)值相同結(jié)果為0又憨,不同值結(jié)果為1
public static void main(String[] args)
{
????????int a=15;
????????int b=2;
????????System.out.println("a 與 b 異或的結(jié)果是:"+(a^b));
}
運(yùn)行結(jié)果a 與 b 異或的結(jié)果是:13
分析上面的程序段:a 的值是15锭吨,轉(zhuǎn)換成二進(jìn)制為1111,而b 的值是2零如,轉(zhuǎn)換成二進(jìn)制為0010,根據(jù)異或的運(yùn)算規(guī)律考蕾,可以得出其結(jié)果為1101 即13。
.位移運(yùn)算符
位移運(yùn)算符包含三種 <<(按位左移運(yùn)算符)蚯窥, >>(按位右移運(yùn)算符) >>>(按位右移補(bǔ)零操作符)
左移運(yùn)算符<<
左移運(yùn)算符<<是將左邊的對(duì)象向左移動(dòng)右邊指定的位數(shù)喜命,并且在低位補(bǔ)0河劝。其實(shí)向左移動(dòng)n位就相當(dāng)于乘以2的n次方
public static void main(String[] args)
{
????int a=2;
????int b=2;
????System.out.println("a 移位的結(jié)果是:"+(a<<b));
}
運(yùn)行結(jié)果a 移位的結(jié)果是:8,分析上面的程序段:
首先從本質(zhì)上來分析赎瞎,2 的二進(jìn)制是00000010,它向左移動(dòng)2 位务甥,就變成了00001000,即8态辛。如果從另一個(gè)角度來分析,它向左移動(dòng)2 位奏黑,其實(shí)就是乘上2 的2 次方编矾,結(jié)果還是8。
右移運(yùn)算符>>
右移是將運(yùn)算符左邊的運(yùn)算對(duì)象窄俏,向右移動(dòng)運(yùn)算符右邊指定的位數(shù)。如果是正數(shù)凹蜈,在高位補(bǔ)零忍啸,如果是負(fù)數(shù)昆烁,則在高位補(bǔ)1,先看下面一個(gè)簡單的例子静尼。
public static void main(String[] args)
{
????int a=16;
????int c=-16;
????int b=2;
????int d=2;
????System.out.println("a 的移位結(jié)果:"+(a>>b));
????System.out.println("c 的移位結(jié)果:"+(c>>d));
}
運(yùn)行結(jié)果 a 的移位結(jié)果:4c 的移位結(jié)果:-4
分析上面的程序段:
a 的值是16,轉(zhuǎn)換成二進(jìn)制是00010000鸭巴,讓它右移兩位成00000100 即4拦盹。
c 的值是-16鹃祖,轉(zhuǎn)換成二進(jìn)制是11101111普舆,讓它右移一位成11111011 即-4。
右移補(bǔ)零運(yùn)算符>>>
右移補(bǔ)零運(yùn)算符用符號(hào)“>>>”表示祖能,是將運(yùn)算符左邊的對(duì)象向右移動(dòng)運(yùn)算符右邊指定的位數(shù)蛾洛,并且在高位補(bǔ)0养铸,其實(shí)右移n 位轧膘,就相當(dāng)于除上2 的n 次方。
public static void main(String[] args)
{
????int a=16;
????int b=2;
????System.out.println("a 移位的結(jié)果是:"+(a>>>b));
}
運(yùn)行結(jié)果 a 移位的結(jié)果是:4
分析上面的程序段:從本質(zhì)上來分析鳞滨,16 的二進(jìn)制是00010000太援,它向右移動(dòng)2 位,就變成了00000100提岔,即4笋敞。如果從另一個(gè)角度來分析碱蒙,它向右移動(dòng)2 位,其實(shí)就是除以2 的2 次方哀墓,結(jié)果還是4喷兼。
好了今天的分享就到這里篮绰,下期我們將分享一個(gè)大型的權(quán)限管理系統(tǒng)使用spring security,包含單點(diǎn)登錄季惯,角色權(quán)限數(shù)據(jù)表設(shè)計(jì),思路圖等贾漏,大家多多關(guān)注我,可以進(jìn)群一起討論(978219630)