C語言位運算子知識總結和例項分析

Belief........發表於2018-09-16

 

位運算應用口訣

清零取反要用與,某位置一可用或

若要取反和交換,輕輕鬆鬆用異或

  1. 與運算子,&:只有前後兩個運算都為1時,結果才為1.​​​​​​​

    a:  0011
    b:  0010
    a&b=0010

     

  2. 或運算子,|:有1位為1,結果便為1。

    a:  0011
    b:  0010
    a|b=0011

     

  3. 異或運算子,^:不相同則為1.

    a:  0011
    b:  0010
    a^b=0001

     

  4. 取反運算子,~:1變0,0變1.

    a:  0011
    ~a= 1100
    b:  0010
    ~b= 1101

     

  5. 移位運算子,<<,   >> : 左移乘2,右移除2,如果超出,則捨棄。

    a<<5
    移前:0000 1111 = 15
    移後:1110 0000 = 224

     

​​​​​​

這裡列舉一些常用的位運算例子。

例一:數字互換

swap(int a,int b)
{
    a=a^b;
    b=b^a;
    a=a^b;
}

例二:求絕對值

  abs( int x ) { 
      int y=x>>31 ; 
      return(x^y)-y;//也可寫作 (x+y)^y 
  }

例三:  X:2,4,8,16轉化成二進位制是10,100,1000,10000。如果減1則變成01,011,0111,01111。兩者做按位與運算,結果如果為0,則X是2的N次方。

#include <stdio.h>
int main()
{
    int n;
	scanf("%d",&n);
	 n&=n-1;
	if(n==0)
		printf("YES!");
	else
		printf("NO!");

}

例三:統計一個整數的二進位制中1的個數。

int CountNumberOfOne(int number)
  {
      int counter = 0;
      while (number)
  {
      counter++;
      number &= number - 1 ;
  }
      return counter;
  }

例四:按位翻轉

 x=((x&0xaaaaaaaa)>>1)|((x&0x55555555)<<1);
  x=((x&0xcccccccc)>>2)|((x&0x33333333)<<2);
  x=((x&0xf0f0f0f0)>>4)|((x&0x0f0f0f0f)<<4);
  x=((x&0xff00ff00)>>8)|((x&0x00ff00ff)<<8);
  x=((x&0xffff0000)>>16)|((x&0x0000ffff)<<16);
  如果無符號32位整數x=311=(100110111)2,那麼經過上述操作後x=3967811584=(11101100100000000000000000000000)2。

 例五:列舉恰好含有k個元素的集合

我們假設全集為含有N個元素為 {0,1,2,…,N-1},那麼程式碼段可以寫成:
  int s = (1 << k) - 1;
  while (!(s & 1 << N)) {
      // 由當前集合 s 計算下一個合法的集合
      int lo = s & -s;       // 求出低位的1
      int lz = (s + lo) & ~s;      // 求出比lo高的0中,最低位的0
      s |= lz;                     // 將lz代表的元素加入集合s
          s &= ~(lz - 1);              // 將比lz位置低的元素全部清空
          s |= (lz / lo / 2) - 1;      // 將集合元素個數補足為k個
      }

ox開頭的代表十六進位制,O開頭的代表八進位制,十進位制開頭無符號

十六進位制:

10——a

11——b

12——c

13——d

14——e

15——f

相關文章