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,¯X表示該位取反。
X & ¯X = 0, 1 & 0 = 0
則~n(2) = ¯X…¯X01…1。
~n + 1 = ¯X…¯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) (以後有再慢慢更新)