c 學習(2)位操作

2021-09-11 22:58:23 字數 3644 閱讀 5716

位操作是十分好用的操作,我在網上進行了搜尋學習,整理了一下。有點水

在計算機中所有資料都是以二進位制的形式儲存的。位運算其實就是直接對在記憶體中的二進位制資料進行操作,因此處理資料的速度非常快。

基本的位操作符有與、或、異或、取反、左移、右移這6種,它們的運算規則如下所示:

符號描述規則&

與兩個位都為1時,結果才為1|或

兩個位都為0時,結果才為0^異或

兩個位相同為0,相異為1~取反

0變1,1變0

>>       

右移   

各二進位全部右移若干位,對無符號數,高位補0,有符號數,各編譯器處理方法不一樣,有的補符號位(算術右移),有的補0(邏輯右移)

<<

左移各二進位全部左移若干位,高位丟棄,低位補0

需要注意的點:

1、 在這6種操作符,只有~取反是單目操作符,其它5種都是雙目操作符。

2、位操作只能用於整形資料,對float和double型別進行位操作會被編譯器報錯。

3、右移是算數右移還是邏輯的得搞清楚,在負數的情況下是不同的。

4、位操作的優先順序比較低,所以最好加上()確保運算順序不出錯。

1、判斷奇偶

只要根據最未位是0還是1來決定,為0就是偶數,為1就是奇數。因此可以用if (a & 1 == 0)代替if (a % 2 == 0)來判斷a是不是偶數。

for (i = 0; i < 100; ++i)  

if (i & 1)

std::cout<2、交換兩個數

一般交換兩個數是用第三個是數進行交換,但是使用位操作就可以節約記憶體,不適用第三個數

void swap(int &a, int &b)

}

可以這樣理解:

第一步  a^=b 即a=(a^b);

第二步  b^=a 即b=b^(a^b),由於^運算滿**換律,b^(a^b)=b^b^a。由於乙個數和自己異或的結果為0並且任何數與0異或都會不變的,所以此時b被賦上了a的值。

第三步 a^=b 就是a=a^b,由於前面二步可知a=(a^b),b=a,所以a=a^b即a=(a^b)^a。故a會被賦上b的值。

再來個例項說明下以加深印象。int a = 13, b = 6;

a的二進位制為 13=8+4+1=1101(二進位制)

b的二進位制為 6=4+2=110(二進位制)

第一步 a^=b  a = 1101 ^ 110 = 1011;

第二步 b^=a  b = 110 ^ 1011 = 1101;即b=13

第三步 a^=b  a = 1011 ^ 1101 = 110;即a=5

3、變換符號

變換符號就是正數變成負數,負數變成正數。

如對於-11和11,可以通過下面的變換方法將-11變成11

1111 0101(二進位制) –取反-> 0000 1010(二進位制) –加1-> 0000 1011(二進位制)

同樣可以這樣的將11變成-11

0000 1011(二進位制) –取反-> 0000 1010(二進位制) –加1-> 1111 0101(二進位制)

因此變換符號只需要取反後加1即可。

變換符號的方法也能用來求絕對值,只需要多一步判斷是否是正數。

4、二進位制逆序

我們知道如何對字串求逆序,現在要求計算二進位制的逆序,如數34520用二進位制表示為:

10000110 11011000

將它逆序,我們得到了乙個新的二進位制數:

00011011 01100001

它即是十進位制的7009。

回顧下字串的逆序,可以從字串的首尾開始,依次交換兩端的資料。在二進位制逆序我們也可以用這種方法,但運用位操作的高低位交換來處理二進位制逆序將會得到更簡潔的方法。類似於歸併排序的分組處理,可以通過下面4步得到16位資料的二進位制逆序:

第一步:每2位為一組,組內高低位交換

10 00 01 10  11 01 10 00

-->01 00 10 01 11 10 01 00

第二步:每4位為一組,組內高低位交換

0100 1001 1110 0100

-->0001 0110 1011 0001

第三步:每8位為一組,組內高低位交換

00010110 10110001

-->01100001 00011011

第四步:每16位為一組,組內高低位交換

01100001 00011011

-->00011011 01100001

對第一步,可以依次取出每2位作一組,再組內高低位交換,這樣有點麻煩,下面介紹一種非常有技巧的方法。先分別取10000110 11011000的奇數字和偶數字,空位以下劃線表示。

原 數   10000110 11011000

奇數字 1_0_0_1_ 1_0_1_0_

偶數字 _0_0_1_0 _1_1_0_0

將下劃線用0填充,可得

原 數   10000110 11011000

奇數字 10000010 10001000

偶數字 00000100 01010000

再將奇數字右移一位,偶數字左移一位,此時將這兩個資料相與即可以達到奇偶位上資料交換的效果了。

原 數          10000110 11011000

奇數字右移 01000011 01101100

偶數字左移 0000100 010100000

相與得到     01001000 11100100

可以看出,結果完全達到了奇偶位的資料交換,再來考慮**的實現——

取x的奇數字並將偶數字用0填充用**實現就是x & 0xaaaa

取x的偶數字並將奇數字用0填充用**實現就是x & 0x5555

因此,第一步就用**實現就是:

x = ((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1);

5、加減乘除

用「異或」和「或」操作實現整數加法運算:對應位數的「異或操作」可得到該位的數值,對應位的「與操作」可得到該位產生的高位進製。

int add(int a, int b)  while(carry != 0);

return add;

}

減法可很容易地轉化為加法

int subtract(int a, int b)
乘法可以通過系列移位和加法完成。最後乙個1可通過b&~(b-1)求得,可通過b& (b-1)去掉,為了高效地得到左移的位數,可提前計算乙個map

int multiply(int a, int b) 

if(neg)

sum = -sum;

return sum;

}

乘法可很容易轉化為減法操作,主要思想與乘法實現類似(除法只能是非小數的,因為二進位制只在整數中)

int divide(int a, int b) 

int q = 0;

for(int i = msb; i >= 0; i--)

if(neg)

return -q;

return q;

}

位操作實現加減乘除四則運算

c++:位操作基礎篇之位操作全面總結

c++位操作

2 C語言位操作

常用位操作 在這裡插入描述 位異或 兩位都相等,結果為0,不相等則為1 左移位 將乙個運算元的各二進位制全部左移若干位,左邊移除出去的二進位制位丟棄,右邊的二進位制位補0。每進行一次左移位操作,得到的結果是原來運算元的一倍 x n x 2 n 位操作與暫存器 暫存器的操作 1 暫存器特定位的清零用 ...

2 c練習 位操作

include define debug debug時需要開啟 ifndef debug define deb format,while 0 endif ifdef debug define deb format,printf format,va args endif define set nth ...

位操作學習

恢復內容開始 1 改變暫存器中某些特定位時,要先讀出暫存器整體的值,然後在這個基礎上修改特定位,再將整個修改後的值放入暫存器中。2 位與 與1位與無變化,與0位與變成0。可以用來對暫存器的值某些特定的位進行清0操作 構建乙個合適的1和0的數來和暫存器的值進行位與操作 例如 要對0xaaaaaaaa,...