位運算符

位運算符

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

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

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

基本介紹

  • 中文名:位運算符
  • 外文名:positional operator
  • 用途程式設計
  • 缺點:只能為整型和字元型數據
  • 性質:運算符的一種
簡介,運算方法,按位與運算,按位或運算,按位異或運算,求反運算,左移運算,右移運算,套用,舉例,優點,注意事項,

簡介

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

運算方法

按位與運算

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

按位或運算

按位或運算符“|”是雙目運算符。 其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。
例如:
9|5
可寫算式如下:
 00001001 | 00000101=00001101
(十進制為13)可見9|5=13
main(){    inta=9,b=5,c;    c=a|b;    printf("a=%d\nb=%d\nc=%d\n",a,b,c);}

按位異或運算

按位異或運算符“^”是雙目運算符。 其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。
參與運算數仍以補碼出現。
例如
9^5
可寫成算式如下:
 00001001 ^ 00000101=00001100
(十進制為12)
main(){    inta=9;    a=a^15;    printf("a=%d\n",a);}

求反運算

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

左移運算

左移運算符“<<”是雙目運算符。左移n位就是乘以2的n次方。 其功能把“<<”左邊的運算數的各二進位全部左移若干位,由“<<”右邊的數指定移動的位數,高位丟棄,低位補0。
1)例: a<<4 指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位後為00110000(十進制48)。
2)例: int i = 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負,那么移位的時候就會出現溢出, 例如: int i = 0x40000000; //16進制的40000000,為2進制的01000000...0000 i = i << 1; 那么,i在左移1位之後就會變成0x80000000,也就是2進制的100000...0000,符號位被置1,其他位全是0,變成了int類型所能表示的最小值,32位的int這個值是,溢出.如果再接著把i左移1位會出現什麼情況呢?
位運算符位運算符
在C語言中採用了丟棄最高位的處理方法,丟棄了1之後,i的值變成了0. 左移里一個比較特殊的情況是當左移的位數超過該數值類型的最大位數時,編譯器會用左移的位數去模類型的最大位數,然後按餘數進行移位,如: int i = 1, j = 0x80000000; //設int為32位 i = i << 33; // 33 % 32 = 1 左移1位,i變成2 j = 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 取決於編譯系統的規定。Turbo C和很多系統規定為補1。
右移對符號位的處理和左移不同: 對於有符號整數來說,比如int類型,右移會保持符號位不變,
例如: int i = 0x80000000; i = i >> 1; //i的值不會變成0x40000000,而會變成0xc0000000 就是說,對於有符號數, 符號位向右移動後,正數的話補0,負數補1, 對於有符號數,在右移時,符號位將隨同移動: 當為正數時, 最高位補0, 而為負數時,符號位為1, 也就是彙編語言中的算術右移.同樣當移動的位數超過類型的長度時,會取餘數,然後移動餘數個位. 最高位是補0或是補1 取決於編譯系統的規定。Turbo C和很多系統規定為補1。 負數10100110 >>5(假設字長為8位),則得到的是 11111101 總之,在C中,左移是邏輯/算術左移(兩者完全相同),右移是算術右移,會保持符號位不變.實際套用中可以根據情況用左/右移做快速的乘/除運算,這樣會比循環效
率高很多.
x>>1;//相當於x/=2x<<1;//相當於x*=2x>>2;//x/=4x<<2;//x*=4x>>3;//x/=8x<<3;//x*=8
以此類推. 無符號:
main() { unsigneda,b; printf("inputanumber:"); scanf("%d",&a); b=a>>5; b=b&15; printf("a=%d\tb=%d\n",a,b); } 
請再看一例!
main(){    chara='a',b='b';    intp,c,d;    p=a;    p=(p<<8)|b;    d=p&0xff;    c=(p&0xff00)>>8;    printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);}

套用

舉例

判斷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<<k)
將int型變數a的第k位置1, 即a=a|(1<<k)
int型變數循環左移k次,即a=a<<k|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)要注意區別位運算符和邏輯運算符的不同。

相關詞條

熱門詞條

聯絡我們