位运算

  有关位运算(与运算,或运算,异或运算,左移和右移)是C/C++语言偏向底层的操作。市面上有很多有关位运算的算法技巧,特在此做了整理。

  1.Bitmap

  什么事Bitmap? Bitmap的核心思想就是“索引”技术,某个比特位作为key,而该比特上的值作为value(可以理解为状态位:0 or 1)。Bitmap既然利用了索引的思想,那么Bitmap这种数据结果的核心就是如何取到某个索引(即定位到某个bit)。

  实现手段上肯定是利用位运算,如果想索引到第 i 比特,可以用如下代码:

(p + i /8) | (0x1 << (i%8)

其中8表示一个字节的比特位数,而p + i /8,表示Bitmap所在的字节,(p + i /8) | (0x1 << (i%8) 便可以索引到当前 i bit位置。使用上面的公式,Bitmap上的两个基本操作:索引和取值:

inline void SetBit(char* p, int pos)

{

    p += pos / BitSize;

    *p = *p | (0x1 << (pos % BitSize));

}



inline int Getbit(char* p, int pos)

{

    return (*(p + pos / BitSize)) | ((pos % BitSize)) ;

}

  2.计算a与b的平均值

  如何利用位运算实现求a与b的平均值呢?先看算法:

  aveg(a, b) = (a & b) + ((a^b) >> 1) 

  a & b,则取出了a与b中相同的位,a与b相同位的平均值自然是自身。a^b取出了不同的位。而不同位的平均值则需要除以2,向左移动1位即可。

  3.不使用加减法,求a与b的和

  不使用加法而实现加法?能够想到解决的方法只能是位的运算了。考察a^b:表示了没用进位的加法,而(a&b)<<1:表示加法的进位。 a^b 与 (a&b)<<1求和,则会得到想要的结果(额,求和?递归迭代完成),代码如下:

int sum(int a, int b)

{

    int sum = 0;

    int carry = 0;



    do 

    {

        sum = a ^ b;

        carry = (a & b) << 1;



        a = sum;

        b = carry;



    } while (carry);



    return sum;

}

 

 

你可能感兴趣的:(位运算)