位運算子及其應用

2021-09-26 08:10:44 字數 3496 閱讀 2884

通過對數字進行移位操作,相比於乘除操作,效率要高。

1、通過位運算代替取模%運算,來判斷num 位奇數或偶數

num & 0x1==1; // 此時num為奇數

num & 0x1==0; // 此時num為偶數

2、通過移位來代替乘除法(乘除數為2的冪)

// 右移n位,表示 num 除以2的n次方

num >> n ;

// 左移n位,表示 num 乘以2的n次方

num << n ;

&      按位與|        按位或^       按位異或~       取反<

>>     右移

1.   按位與運算

按位與運算子"&"是雙目運算子。

其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。

例如:9&5可寫算式如下: 00001001 (9的二進位制補碼)&00000101 (5的二進位制補碼) 00000001 (1的二進位制補碼)可見9&5=1。

按位與運算通常用來對某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 運算 ( 255 的二進位制數為0000000011111111)。

main()
2.按位或運算按位或運算子「|」是雙目運算子。

其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有乙個為1時,結果位就為1。參與運算的兩個數均以補碼出現。

例如:9|5可寫算式如下: 00001001|00000101

00001101 (十進位制為13)可見9|5=13

main(){

int a=9,b=5,c;

c=a|b;

printf("a=%d\nb=%d\nc=%d\n",a,b,c);

3.按位異或運算按位異或運算子「^」是雙目運算子。

其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。參與運算數仍以補碼出現。

例如9^5可寫成算式如下: 00001001^00000101 00001100 (十進位制為12)

4. 求反運算

求反運算子~為單目運算子,具有右結合性。 

其功能是對參與運算的數的各二進位按位求反。

例如~9的運算為: ~(0000000000001001)結果為:1111111111110110

5. 左移運算

左移運算子「<

其功能把「<

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這個值是-2147483648,溢位.如果再接著把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補最低位

6. 右移運算

右移運算子「>>」是雙目運算子。右移n位就是除以2的n次方

其功能是把「>>」左邊的運算數的各二進位全部右移若干位,「>>」右邊的數指定移動的位數。

例如:設 a=15,a>>2 表示把000001111右移為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以此類推.

無符號:

位運算子及其使用

title date br description c語言位運算子及其使用 2020 04 23 03 01 19 0700 位運算 c語言 c提供了按位邏輯運算子和移位運算子 運算子含義 按位取反 按位與 按位異或 掩碼所謂掩碼就是一些設定為開 1 或關 0 的位組合 例如 include def...

位運算子,「,」逗號運算子,

位運算子有 按位與 按位或 按位異或 按位取反 優先順序從高到低,依次為 按位與運算有兩種典型用法,一是取乙個位串資訊的某幾位,如以下 擷取x的最低7位 x 0177。二是讓某變數保留某幾位,其餘位置0,如以下 讓x只保留最低6位 x x 077。按位或運算的典型用法是將乙個位串資訊的某幾位置為1。...

運算子之位運算子

右移 負數 無符號右移 或 異或 與 非 說明 位運算子都是作用在二進位製上的 比如 n 50 n 1 結果是多少?100 n 2 結果是多少?200 n 5 結果是多少?1600 為什麼會是這樣的呢?運算的邏輯如下 1,n 50 2,n的二進位制是 0011 0010 3,0011 0010 左移...