JAVA 位運(yùn)算

計(jì)算機(jī)和真實(shí)生活中不同,一個(gè)數(shù)在計(jì)算機(jī)中只能以二進(jìn)制(0或者1)的方式表示,現(xiàn)實(shí)生活中主要以十進(jìn)制表示,在二進(jìn)制的標(biāo)示中,最高位是符號(hào)位,最高位如果為0 ,則表示該數(shù)的十進(jìn)制表示為正數(shù),如果最高位為1,則該數(shù)位負(fù)數(shù)。以十進(jìn)制3為例,改為8位的二進(jìn)制,則是[0000 0011],如果是-3轉(zhuǎn)換為8位的二進(jìn)制是[1000 0011].在這里[0000 0011] 與3表示的意思相同 ,不過(guò)[0000 0011] 是機(jī)器數(shù),3為真值。

原碼, 反碼, 補(bǔ)碼的基礎(chǔ)概念

1. 原碼

原碼:是最簡(jiǎn)單的機(jī)器數(shù)表示法。用最高位表示符號(hào)位,‘1’表示負(fù)號(hào),‘0’表示正號(hào)。其他位存放該數(shù)的二進(jìn)制的絕對(duì)值。

若以1000? 0010 為例子

最高位為‘1’,表示這是一個(gè)負(fù)數(shù),其他七位為‘000? 0010’

即(0*2^7)+(0*2^6)+(0*2^5)+(0*2^4)+(0*2^3)+(0*2^2)+(1*2^1)+(0*2^0)=2(‘^’表示冪運(yùn)算符)

所以1000? 0010 是-2

2.反碼

反碼:正數(shù)的反碼還是等于原碼

負(fù)數(shù)的反碼就是他的原碼除符號(hào)位外,按位取反

若以帶符號(hào)位的八位二進(jìn)制數(shù)為例:

3是正數(shù),反碼與原碼相同,則可以表示為0000 0011

-3的原碼是1000 0011,符號(hào)位保持不變,低七位(000 0011)按位取反得(100? 1100)

3.補(bǔ)碼

補(bǔ)碼:正數(shù)的補(bǔ)碼等于他的原碼

負(fù)數(shù)的補(bǔ)碼等于反碼+1。

(這只是一種算補(bǔ)碼的方式,多數(shù)書(shū)對(duì)于補(bǔ)碼就是這句話)

前言

日常開(kāi)發(fā)中位運(yùn)算不是很常用,但是巧妙的使用位運(yùn)算可以大量減少運(yùn)行開(kāi)銷,優(yōu)化算法。舉個(gè)例子,翻轉(zhuǎn)操作比較常見(jiàn),比如初始值為1,操作一次變?yōu)?,再操作一次變?yōu)???赡艿淖龇ㄊ鞘褂萌具\(yùn)算符,判斷原始值為1還是0,如果是1,設(shè)置為0,否則設(shè)置為0.但是使用位運(yùn)算,不用判斷原始值,直接改變值就可以。當(dāng)然,一條語(yǔ)句可能對(duì)代碼沒(méi)什么影響,但是在高重復(fù),大數(shù)據(jù)量的情況下將會(huì)節(jié)省很多開(kāi)銷。

位運(yùn)算符

一些只需要一個(gè)操作數(shù)的運(yùn)算符稱為一元運(yùn)算符(或單目運(yùn)算符)。

二元運(yùn)算是由兩個(gè)元素形成第三個(gè)元素的一種規(guī)則。例如數(shù)的加法乘法;更一般地,由兩個(gè)集合形成第三個(gè)集合的產(chǎn)生方法或構(gòu)成規(guī)則稱為二次運(yùn)算。(或雙目運(yùn)算符)

位邏輯運(yùn)算符

位邏輯運(yùn)算符包含 4 個(gè):&(與)、|(或)、~(非)和 ^(異或)。除了 ~(即位取反)為單目運(yùn)算符外,其余都為雙目運(yùn)算符。表 1 中列出了它們的基本用法。

位與運(yùn)算符

位與運(yùn)算符為&,其運(yùn)算規(guī)則是:參與運(yùn)算的數(shù)字,低位對(duì)齊,高位不足的補(bǔ)零,如果對(duì)應(yīng)的二進(jìn)制位同時(shí)為 1,那么計(jì)算結(jié)果才為 1,否則為 0。因此,任何數(shù)與 0 進(jìn)行按位與運(yùn)算,其結(jié)果都為 0。

例如下面的表達(dá)式:100&0

0110 0100? ---> 100

&0000 0000 --->? 0

? 0000 0000 --->? 0

代碼實(shí)現(xiàn):

? ? ? int x = 100,y = 0;

? ? ? int z = x&y;

? ? ? System.out.println("運(yùn)算結(jié)果:"+z);

//運(yùn)算結(jié)果:0

位或運(yùn)算符

位或運(yùn)算符為|,其運(yùn)算規(guī)則是:參與運(yùn)算的數(shù)字,低位對(duì)齊,高位不足的補(bǔ)零。如果對(duì)應(yīng)的二進(jìn)制位只要有一個(gè)為 1,那么結(jié)果就為 1;如果對(duì)應(yīng)的二進(jìn)制位都為 0,結(jié)果才為 0。

下面是一個(gè)使用位或運(yùn)算符的表達(dá)式:4|7

0000 0100--->4

|? ? 0000 0111--->7

? ? 0000 0111--->7

代碼驗(yàn)證:

? int x = 4,y = 7;

? ? ? int z = x|y;

? ? ? System.out.println("運(yùn)算結(jié)果:"+z);

//運(yùn)算結(jié)果:7

位異或運(yùn)算符

位異或運(yùn)算符為^,其運(yùn)算規(guī)則是:參與運(yùn)算的數(shù)字,低位對(duì)齊,高位不足的補(bǔ)零,如果對(duì)應(yīng)的二進(jìn)制位相同(同時(shí)為 0 或同時(shí)為 1)時(shí),結(jié)果為 0;如果對(duì)應(yīng)的二進(jìn)制位不相同,結(jié)果則為 1

下面是一個(gè)使用位異或運(yùn)算符的表達(dá)式:4^7

0000 0100--->4

^? 0000 0111--->7

? ? 0000 0011--->3

代碼驗(yàn)證:

? ? ? int x = 4,y = 7;

? ? ? int z = x^y;

? ? ? System.out.println("運(yùn)算結(jié)果:"+z);

//運(yùn)算結(jié)果:3

位取反運(yùn)算符

位取反運(yùn)算符為~,其運(yùn)算規(guī)則是:只對(duì)一個(gè)操作數(shù)進(jìn)行運(yùn)算,將操作數(shù)二進(jìn)制中的 1 改為 0,0 改為 1。

下面是一個(gè)使用位取反運(yùn)算符的表達(dá)式: ~5

位移運(yùn)算符

位移運(yùn)算符用來(lái)將操作數(shù)向某個(gè)方向(向左或者右)移動(dòng)指定的二進(jìn)制位數(shù)。表 2 列出了 Java 語(yǔ)言中的兩個(gè)位移運(yùn)算符,它們都屬于雙目運(yùn)算符。

左位移運(yùn)算符

左移位運(yùn)算符為?,其運(yùn)算規(guī)則是:按二進(jìn)制形式把所有的數(shù)字向左移動(dòng)對(duì)應(yīng)的位數(shù),高位移出(舍棄),低位的空位補(bǔ)零。

例如,將整數(shù) 7向左位移 1 位的過(guò)程如下:

? ? ? ? ? ? ? ? 0000 0111

? ? ? ? ? ? ? ? 00000 1110---->14

原來(lái)數(shù)的所有二進(jìn)制位都向左移動(dòng) 1 位。原來(lái)位于左邊的最高位 0 被移出舍棄,再向尾部追加 0 補(bǔ)位。最終到的結(jié)果是14,相當(dāng)于原來(lái)數(shù)的 2 倍。

代碼驗(yàn)證:

? ? ? int x = 7;

? ? ? int z = x <<1;

? ? ? System.out.println("運(yùn)算結(jié)果:"+z);

? ? ? //運(yùn)算結(jié)果:14

右位移運(yùn)算符

右位移運(yùn)算符為?,其運(yùn)算規(guī)則是:按二進(jìn)制形式把所有的數(shù)字向右移動(dòng)對(duì)應(yīng)的位數(shù),低位移出(舍棄),高位的空位補(bǔ)零。

例如,將整數(shù) 7向右位移 1 位的過(guò)程如下:

? ? ? ? ? ? ? ? ? ? ? ? 0000 0111

0000 00111---->3

原來(lái)數(shù)的所有二進(jìn)制位都向右移動(dòng) 1 位。原來(lái)位于右邊的最低位 1 被移出舍棄,再向最高位追加 0 補(bǔ)位。最終到的結(jié)果是 3,相當(dāng)于原數(shù)整除 2 余數(shù)舍棄的結(jié)果。

復(fù)合位賦值運(yùn)算符

所有的二進(jìn)制位運(yùn)算符都有一種將賦值與位運(yùn)算組合在一起的簡(jiǎn)寫形式。復(fù)合位賦值運(yùn)算符由賦值運(yùn)算符與位邏輯運(yùn)算符和位移運(yùn)算符組合而成。表 3 列出了組合后的復(fù)合位賦值運(yùn)算符。

? int a = 1;

? ? ? int b = 2;

? ? ? int c = 3;

? ? ? a &= 4;

? ? ? a |= 4;

? ? ? a ^= c;

? ? ? a -= 6;

? ? ? b >>= 1;

? ? ? c <<= 1;

? ? ? System.out.println("a = " + a);

? ? ? System.out.println("b = " + b);

? ? ? System.out.println("c = " + c);

????????a = 1

????????b = 1

????????c = 6

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容