無論說是在哪一門計(jì)算機(jī)語言待笑,位操作運(yùn)算對(duì)于計(jì)算機(jī)來說肯定是最高效的,因?yàn)橛?jì)算機(jī)的底層是按就是二進(jìn)制祟绊,而位操作就是為了節(jié)省開銷驯嘱,加快程序的執(zhí)行速度义郑,以及真正的實(shí)現(xiàn)對(duì)數(shù)的二進(jìn)制操作。
使用位操作杈曲,很多代碼看起來會(huì)很簡(jiǎn)潔驰凛,并且執(zhí)行速度也會(huì)隨之提高胸懈。在大多數(shù)編程語言中都會(huì)有 << 和 >>
這兩個(gè)符號(hào)向左的就是左移,反之則是右移這個(gè)符號(hào)的左邊就是需要操作的數(shù)恰响,而右邊就代表了對(duì)這個(gè)數(shù)移動(dòng)多少位趣钱。
1.具體位操作
- 左移( << ):
左移幾位就是將這個(gè)數(shù)再乘以2的幾次方,例如說 4 << 2 其結(jié)果就是16胚宦,也就是將這個(gè)數(shù)化作為2進(jìn)制的數(shù)然后向左移動(dòng)兩位首有,最右邊的空位就補(bǔ)0. - 右移( >> ):
右移就剛好相反,但是也不是完全一樣枢劝,他是向右移動(dòng) n 位井联,如果說這個(gè)數(shù)本來就是正的,那么和左移剛好相反就直接除以 2 的 n 次方位您旁,但是如果是負(fù)數(shù)的話在這個(gè)數(shù)向右移動(dòng) n 位后我們?cè)谇懊娴目瘴谎a(bǔ)的是 0 烙常。也就是右移的話是與數(shù)相關(guān)的問題。右移一個(gè)很明顯的應(yīng)用就是在二分法的時(shí)候我們就可以直接右移一位鹤盒,顯然速度會(huì)提高军掂。 - 超級(jí)右移( >>> ):
剛剛說了右移其實(shí)還是需要按照情況來的,有時(shí)候就不一定是正數(shù)昨悼,我們就可能補(bǔ) 1 蝗锥,但是我們期望結(jié)果就是這個(gè)數(shù)除以 2 的 n 次方,我們就可以使用這個(gè)無視正負(fù)號(hào)的右移操作 >>> 率触,也就是說他是在任何情況下都是給最高位添加 0 终议。 - 與操作( & ):
與操作就是把兩個(gè)數(shù)轉(zhuǎn)化為二進(jìn)制的數(shù),然后再把這兩個(gè)數(shù)葱蝗,從最低位每位對(duì)其穴张,同 1 結(jié)果為 1 否則全為 0。 - 或操作( | ):
操作同上只是這個(gè)是同 0 為 0两曼,其他都是1皂甘。 - 取反操作( ~ ):
二進(jìn)制的0 變 1 , 1 變 0悼凑。 - 異或( ^ ):
異或有一條很重要的性質(zhì)偿枕,用的非常多就是一個(gè)數(shù)異或同一個(gè)數(shù)兩次結(jié)果還是那個(gè)數(shù)。
上面的與或操作會(huì)發(fā)現(xiàn)他們有單符號(hào)的還有雙符號(hào)的户辫,不要搞混了單符號(hào)的不僅僅就是位操作渐夸,他們還是邏輯操作,而雙符號(hào)的僅僅就是邏輯操作渔欢。并且他們有區(qū)別例如 & 和 && 當(dāng)他們都作為邏輯操作的墓塌,前者就是對(duì)一個(gè)表達(dá)式一直判斷完畢才會(huì)出現(xiàn)他的值,而后者則是判斷一半如果知道為假或真他就不再判斷了,這也就是我們看到的大多數(shù)的 if 判斷中是用的雙與苫幢,而非單與访诱。
2.實(shí)際應(yīng)用:
- 第一個(gè)就是兩個(gè)數(shù)交換,這個(gè)一般有三種方式:
第一個(gè):臨時(shí)變量
int i=3,j=8,temp=0;
temp=i;
i=j;
j=temp;
第二個(gè):使用加減法
int i=3,j=8;
i=j+i;
j=i-j;
i=i-j;
第三個(gè):位操作
int i=3,j=8;
i=i^j;
j=i^j;
i=i^j;
這個(gè)地方就是用了異或的重要性質(zhì)
- 第二個(gè)就是進(jìn)制轉(zhuǎn)換了:
基本思路就是先把數(shù)轉(zhuǎn)為二進(jìn)制的數(shù)韩肝,然后如果要 16 進(jìn)制那么就4位取盐数,8進(jìn)制3位取,但是又怎么取這個(gè)4位或者3位呢伞梯,這里與操作就能派上用場(chǎng)取四位我們可以直接與上 15 玫氢,三位就是 7 了,例如:
int num=60;
int n1=num & 15;
int tmp=num >>> 4;
int n2=tmp & 15;
System.out.println("n1: "+n1+" n2 "+n2);