Discussion:Bit Operation(& ,| ,~,,^)

來源:互聯網
上載者:User

什麼是位?

簡單來說,位就是1和0,在電腦中做的每一件事都是由它們組成的。電腦中所有的資料使用的是位。一個位元組由8個位組成;一個字由兩個位元組組成,即16個位;而一個雙字由四個位元組組成,即32個位。由於位元運算直接對記憶體資料進行操作,不需要轉成十進位,因此處理速度非常快

位元運算有哪些操作符?

& ,| ,~,<<,>>,^

(補充,邏輯運算子是 ||   , &&  ,  !這些和位元運算符大大不同)

它們分別的意思是:

& 與運算子   | 或運算子  ~ 取反運算子   >> 右移運算子   << 左移運算子    ^ 異或運算子  
 

下面我們看看這些操作符是怎麼操作的:

&:

(1).運算規則:有0變0,無0為1

(2).判斷奇偶性

a&1  = 0 偶數 

a&1 =  1 奇數

(3).可以用來取位操作

如:一個數 and 1的結果就是取二進位的最末位 

(4).判斷一個數的二進位第n位是否為1的方法是:把一個n位為1,其它位為0與待判斷的數進行與運算

我們看下例子(看是否存在D盤,主要是根據與運算是否存在1000):

DWORD d = GetLogicalDrives();if((d&8)>0)   //是否存在D盤{    SetDlgItemText(hwnd,IDC_EDTNAME4,TEXT("存在D盤"));}else{    SetDlgItemText(hwnd,IDC_EDTNAME4,TEXT("不存在D盤"));}

(5).求餘最佳化(x%(2n)=x&(2n-1)

 | ()

(1).運算規則:有1變1,無1變0

(2).一個數or 1的結果就是把二進位最末位強行變成1

~(取反)

(1).取反運算的定義是把記憶體中的0和1全部取反。使用not運算時要格外小心,你需要注意整數類型有沒有符號。如果not的對象是不帶正負號的整數(不能表示負數)。

如:

#include <stdio.h>int main(void){    unsigned short a=100;    a = ~a;    printf( "%d/n", a );    return 0;}

如上面的一段程式 算出來為 65435  而它的上界位65536 所以算出來的結果是它們的差,因為無符號類型的數是用$0000到$FFFF依次表示的。


<<(左移)

(1).如A<<B:是A轉換為二進位後向左移動B位

(2).左移3相當於乘以2的3次方
可以使用(1 << 16 )-1來表示個常量 如#defien Max_N (1 << 16 )-1, 因為這個值表示65535(很有用,有時大量的乘除運算可用移位代替,效率會很高!)


>>(右移)

(1).A>>B:是A轉換為二進位後向右移動B位

(2).右邊的位被擠掉。對於左邊移出的空位,如果是正數則空位補0,若為負數,可能補0或補1,這取決於所用的電腦系統。

(3).右移3相當於除以2的3次方

下面是個例子,看電腦中存在多少磁碟(主要是右移!)

void countIt(HWND hwnd){       DWORD n = GetLogicalDrives();       int count = 0;//計數器      while(n>0)       {           if((n&1)>0)//判斷最後一位是否為1           {               count ++;           }              n = n>>1;//繼續右移        }        TCHAR cD[256];       itoa(count,cD,10);       MessageBox(NULL,cD,TEXT("hello!"),MB_OK);   }  

 ^:(異或)

1.可以用一句話理解:是不是不一樣 (不一樣為1,一樣為0)

2.兩次異或同一個數還是它本身(如:(a ^b)^b=a)

3.(a ^ b) ^ b = a,像這種異或運算可用於加密 用兩次異或 b位密碼

4.另外還有一個是不引入第三變數,交換兩個變數的值 (設 a=a1,b=b1) 

5.兩個位元異或的結果為兩者之差的絕對值


一些位元運算的例子:

   功能              |           樣本            |    位元運算   ----------------------+---------------------------+--------------------   去掉最後一位          | (101101->10110)           | x >> 1   在最後加一個0         | (101101->1011010)         | x << 1   在最後加一個1         | (101101->1011011)         | x << 1+1   把最後一位變成1       | (101100->101101)          | x | 1   把最後一位變成0       | (101101->101100)          | x | 1-1   最後一位取反          | (101101->101100)          | x ^ 1   把右數第k位變成1      | (101001->101101,k=3)      | x | (1 <<(k-1))   把右數第k位變成0      | (101101->101001,k=3)      | x & ~ (1 << (k-1))   右數第k位取反         | (101001->101101,k=3)      | x ^ (1 << (k-1))   取末三位              | (1101101->101)            | x & 7   取末k位               | (1101101->1101,k=5)       | x & (1 << k-1)   取右數第k位           | (1101101->1,k=4)          | x >> (k-1) & 1   把末k位變成1          | (101001->101111,k=4)      | x | (1 << k-1)   末k位取反             | (101001->100110,k=4)      | x ^ (1 << k-1)   把右邊連續的1變成0    | (100101111->100100000)    | x & (x+1)   把右起第一個0變成1    | (100101111->100111111)    | x | (x+1)   把右邊連續的0變成1    | (11011000->11011111)      | x | (x-1)   取右邊連續的1         | (100101111->1111)         | (x ^ (x+1)) >> 1   去掉右起第一個1的左邊 | (100101000->1000)         | x & (x ^ (x-1))   


位元運算求絕對值:

 x >> 31是二進位的最高位,它用來表示x的符號。如果它為0(x為正),則~ (x >> 31) + 1等於$00000000,異或任何數結果都不變;如果最高位為1(x為負),則~ (x >> 31) + 1等於$FFFFFFFF,x異或它相當於所有數位取反,異或完後再加1。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.