位運算符

位運算符

位操作是程序設計中對位模式按位或二進位數的一元和二元操作。

在許多古老的微處理器上,位運算比加減運算略快,通常位運算比乘除法運算要快很多。

在徠現代架構中,情況並非如此:位運算的運算速度通常與加法運算相同(仍然快於乘法運算)。

基本簡介


位運算符用來對二進位位進行操作,Java中提供了如下表所示的位運算符:位運算符中,除~以外,其餘均為二元運算符。
操作數只能為整型和字元型數據。C語言中六種位運算符:
&按位與
|按位或
^按位異或
~取反
<<左移
>>右移

運算方法


按位與運算

按位與運算符"&"是雙目運算符。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1,否則為0。參與運算的數以補碼方式出現。
位運算符
位運算符
例如:9&5可寫算式如下:00001001(9的二進位補碼)&00000101(5的二進位補碼)00000001(1的二進位補碼)可見9&5=1。按位與運算通常用來對某些位清0或保留某些位。例如把a的高八位清0,保留低八位,可作a&255運算(255的二進位數為11111111)。

按位或運算

按位或運算符“|”是雙目運算符。其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。
例如:
可寫算式如下:
(十進位為13)可見9|5=13

按位異或運算

按位異或運算符“^”是雙目運算符。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。
參與運算數仍以補碼出現。
例如
可寫成算式如下:
(十進位為12)

求反運算

求反運算符~為單目運算符,具有右結合性。其功能是對參與運算的數的各二進位按位求反。
例如
的求反運算為:
結果為:

左移運算

左移運算符“<<”是雙目運算符。左移n位就是乘以2的n次方。其功能把“<<”左邊的運算數的各二進位全部左移若干位,由“<<”右邊的數指定移動的位數,高位丟棄,低位補0。
1)例:a<<4指把a的各二進位向左移動4位。如a=00000011(十進位3),左移4位後為00110000(十進位48)。
2)例:inti=1;i=i<<2;//把i里的值左移2位也就是說,1的2進位是000...0001(這裡1前面0的個數和int的位數有關,32位機器,gcc里有31個0),左移2位之後變成000...0100,也就是10進位的4,所以說左移1位相當於乘以2,那麼左移n位就是乘以2的n次方了(有符號數不完全適用,因為左移有可能導致符號變化,下面解釋原因)
位運算符
位運算符
需要注意的一個問題是:int類型最左端的符號位和移位移出去的情況.我們知道,int是有符號的整形數,最左端的1位是符號位,即0正1負,那麼移位的時候就會出現溢出,例如:inti=0x40000000;//16進位的40000000,為2進位的01000000...0000i=i<<1;那麼,i在左移1位之後就會變成0x80000000,也就是2進位的100000...0000,符號位被置1,其他位全是0,變成了int類型所能表示的最小值,32位的int這個值是,溢出。如果再接著把i左移1位會出現什麼情況呢?
在C語言中採用了丟棄最高位的處理方法,丟棄了1之後,i的值變成了0.左移里一個比較特殊的情況是當左移的位數超過該數值類型的最大位數時,編譯器會用左移的位數去模類型的最大位數,然後按餘數進行移位,如:inti=1,j=0x80000000;//設int為32位i=i<<33;//33%32=1左移1位,i變成2j=j<<33;//33%32=1左移1位,j變成0,最高位被丟棄在用gcc編譯這段程序的時候編譯器會給出一個warning,說左移位數>=類型長度。那麼實際上i,j移動的就是1位,也就是33%32后的餘數。在gcc下是這個規則,不同編譯器可能會不完全相同.
總之左移就是:丟棄最高位,0補最低位

右移運算

右移運算符“>>”是雙目運算符。右移n位就是除以2的n次方
其功能是把“>>”左邊的運算數的各二進位全部右移若干位,“>>”右邊的數指定移動的位數。
例徠如:設a=15,a>>2表示把00001111右移為00000011(十進位3)。應該說明的是,對於有符號數,在右移時,符號位將隨同移動。當為正數時,最高位補0,而為負數時,符號位為1,最高位是補0或是補1取決於編譯系統的規定。TurboC和很多系統規定為補1。
右移對符號位的處理和左移不同:對於有符號整數來說,比如int類型,右移會保持符號位不變,
例如:inti=0x80000000;i=i>>1;//i的值不會變成0x40000000,而會變成0xc0000000就是說,對於有符號數,符號位向右移動后,正數的話補0,負數補1,對於有符號數,在右移時,符號位將隨同移動:當為正數時,最高位補0,而為負數時,符號位為1,也就是彙編語言中的算術右移。同樣當移動的位數超過類型的長度時,會取餘數,然後移動餘數個位.最高位是補0或是補1取決於編譯系統的規定。TurboC和很多系統規定為補1。負數10100110>>5(假設字長為8位),則得到的是11111101總之,在C中,左移是邏輯/算術左移(兩者完全相同),右移是算術右移,會保持符號位不變。實際應用中可以根據情況用左/右移做快速的乘/除運算,這樣會比循環效
率高很多.
以此類推.無符號:
請再看一例!

應用


舉例

判斷int型變數a是奇數還是偶數a&1=0偶數a&1=1奇數
取int型變數a的第k位(k=0,1,2……sizeof(int)),即a>>k&1
將int型變數a的第k位清0,即a=a&~(1<
將int型變數a的第k位置1,即a=a|(1<
int型變數循環左移k次,即a=a<>16-k(設sizeof(int)=16)
int型變數a循環右移k次,即a=a>>k|a<<16-k(設sizeof(int)=16)

優點

C語言位運算符在某些編程中如果靈活應用,則可以大大提高程序的執行效率,使程序執行時速度更高。
C語言主要應用於嵌入式開發、智能電器、通信行業等一些對效率和時間都要求很高的應用領域中,學好位運算符,在程序開發中靈活應用位運算符,往往能在這些應用中起到事半功倍的效果。

注意事項


位運算符使用的注意事項:
(1)位運算是對位元組或字中的實際二進位位進行檢測、設置或移位,它只適用於字元型和整數型變數以及它們的變體,對其它數據類型不適用。
(2)關係運算和邏輯運算表達式的結果只能是1或0,而位運算的結果可以取0或1以外的值。
(3)要注意區別位運算符和邏輯運算符的不同。
  • 目錄