1. 程式人生 > >C/C++ bit 位操作

C/C++ bit 位操作

1)  函式實現交換兩個int型變數的值,要求不定義任何中間變數。

C / C++ 版:

void Swap(int *a, int *b)

{

*a^=*b;

   *b^=*a;

   *a^=*b;

}

C++ 版:

void Swap(int &a, int &b)

{

a^=b;

   b^=a;

   a^=b;

}

分析一下:

(a ^ b = s)       (b ^ s = a)

0 ^ 1 = 1        1 ^ 1 = 0

1 ^ 0 = 1        0 ^ 1 = 1

1 ^ 1 = 0        1 ^ 0 = 1

0 ^ 0 = 0        0 ^ 0 = 0

歸結一下:1. 兩個數相異或,相同的位清0,不同的位置1。 (所以才有了 XOR eax, eax ;eax清零)

          2. s = (a ^ b); (b ^ s) == a ? Yes. 異或加密解密的基礎.

2) 摘自《高效程式的奧祕》一書。英文書名<Hacker’s Delight>,譯為《黑客的竊喜》

   獲得字尾0bit的個數。(從低位開始的連續的0bit,間接地求最低位的1bit的位置)

int ntz(unsigned x)  {         // Number of trailing zeros.

    int n;

if (x == 0) return(32);

n = 1;

if ((x & 0x0000FFFF) == 0) {n = n +16; x = x >>16;}

if ((x & 0x000000FF) == 0) {n = n + 8; x = x >> 8;}

        if ((x & 0x0000000F) == 0) {n = n + 4; x = x >> 4;}

        if ((x & 0x00000003) == 0) {n = n + 2; x = x >> 2;}

        return n - (x & 1);

}

3) 除了最低位的bit1,其餘位全清0. <Hacker’s Delight>一書。

   n = n & (-n)   < - - - - > n = n & (~n + 1)

分析一下:

假設n(2) = X…X10…0。其中每個X代表bit值並不都是相同,0的個數≥0,&#175;X表示該位取反。

X & &#175;X = 0, 1 & 0 = 0

    則~n(2) = &#175;X…&#175;X01…1。

      ~n + 1 = &#175;X…&#175;X10…0。

         n & (~n + 1) = 0…010…0

4) 清最低位的bit1,其他不變。

   n = n & (n – 1);

   則 n – 1 = X…X01…1

      n & (n - 1) = X…X00…0

5) 獲得bit1的個數。(統計)

   我們常用的方法:

int Get1BitCount(unsigned int x)

{

   int n = 0;

while (x > 0) {

    if (x & 0x1) n++;

    x >>= 1;

}

return n;

}

另一種更好的辦法:

int Get1BitCount(unsigned int x)

{

    int  n = 0;

    while (x > 0) {

n++;

x = x & (x - 1);

     }

     return n;

}

6) 求unsigned int型數一共有多少bit?(網上看到有人問)

 int  nCount = Get1BitCount((unsigned int)~0);

 求別的資料型別的位數,要過載Get1BitCount(或者直接用temlate來實現)。

 不過覺得像上面這樣求法,太浪費了,不是嗎?

 int GetTotalBit(void)

{

    unsigned int x = ~0;

    int  n = 0;

    while (x > 0) {

n += 8;

x >>= 8;

     }

     return n;

}

7)  清除低位到高位的n個bit1。

    while (--n > 0) {

        x = x & (x - 1);

}

8)  (以後有再慢慢更新)