位运算有很大的妙用,在C语言中发扬光大。有什么作用呢?在数据结构和算法中有个很重要的概念就是:时间和空间。位运算就可以提高时间的效率和空间的利用率。


一、位运算增加空间的利用率。

      没有什么神奇之处,只是以紧凑的二进制格式来描述数据结构,应用之多举不胜举。记住,最小的存储单元是bit而不是byte


二、位运算提高时间的效率。

      根本原因是读取内存次数少,我们知道CPU一次读取内存的最大字节数和字长有关,正是因为把数据压缩在有限的数据结构中,读取内存的次数大大减少。


应用举例:

    1、如何不使用中间变量,交换两个变量?


a = a ^ b;
b = a ^ b;
a = a ^ b;

    可能会有人说使用加减法也可以,如:

a = a + b;
b = a - b;
a = a - b;

    但是加减法是有副作用的,容易导致数据溢出。


2、状态的改变,我们可能经常写类似下面的代码:


if (b) {
     b = false;
} else {
     b = true;
}

      或者更精简一点

b = b ? false : true;

      但依然会别扭,因为你要改变一个标志的状态,首先要知道原有状态,使用位运算可以避免

b ^= b;


3、位向量,很多底层库中都有位向量的类,可用于很多场合,高效环保。我自己写了一个位向量,求解1亿一下素数,时间不到3秒,内存占用不到13M,可见位运算的威力。


#define LONG_BIT_LENGTH sizeof(long)
#define BIT_SHIFT_UNIT (LONG_BIT_LENGTH/8 + 1)
#define BIT_MASK (LONG_BIT_LENGTH-1)
//位向量结构:方便同时使用多个位向量
typedef struct tag_bit_vector {
    long *bit_buffer;       //数据区
    long max_bit_num;       //总bit数
}TBitVector;
//========================================================================================
//分配一个位向量
TBitVector *mallc_bit_vector(long bit_max) {
    TBitVector *pbit_vector = 0;
    pbit_vector = (TBitVector *)malloc(sizeof(TBitVector));
    if (pbit_vector == NULL) return NULL;
    pbit_vector->bit_buffer = (long *)calloc(LONG_BIT_LENGTH, (bit_max + BIT_MASK) >> BIT_SHIFT_UNIT);
    if (pbit_vector->bit_buffer == NULL) return NULL;
    pbit_vector->max_bit_num = bit_max;
    return pbit_vector;
}
//释放一个位向量
void free_bit_vector(TBitVector *bit_vector) {
    free(bit_vector->bit_buffer);
    free(bit_vector);
}
//========================================================================================
//设置
void set_bit_vector(TBitVector *bit_vector, long idx) {
    if (idx >= bit_vector->max_bit_num) return;
    bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] |= 1 << (idx & BIT_MASK);
}
//清除
void cls_bit_vector(TBitVector *bit_vector, long idx) {
    if (idx >= bit_vector->max_bit_num) return;
    bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] &= ~(1 << (idx & BIT_MASK));
}
//探测
int test_bit(TBitVector *bit_vector, long idx) {
    if (idx >= bit_vector->max_bit_num) return 0;
    return bit_vector->bit_buffer[idx >> BIT_SHIFT_UNIT] & (1 << (idx & BIT_MASK));
}


   求解素数代码:

int sievePrime(TBitVector *pBitVerctor, unsigned long prime)
{
    unsigned long i;
    if (prime*prime >= pBitVerctor->max_bit_num)
    {
        return 0;
    }
    for (i=prime<<1; i<pBitVerctor->max_bit_num; i+=prime)
    {
        set_bit_vector(pBitVerctor, i);
    }
    return -1;
}
//测试
#define PRIME_NUMBER_MAX 100000000
int main(int argc, char *argv[])
{
    int milisection = 0;
    int i = 0;
    int primeCount = 0;
    struct timeval start;
    struct timeval end;
    TBitVector *pdata = mallc_bit_vector(PRIME_NUMBER_MAX);
    milisection = GetTickCount(&start);
    for (i=2; i<PRIME_NUMBER_MAX; i++)
    {
        if (test_bit(pdata, i))
            continue;
        if (sievePrime(pdata, i) == 0)
        {
            break;
        }
    }
                                                                  
    GetTickCount(&end);
    printf("times : %d\n", (end.tv_sec * 1000 * 1000 + end.tv_usec) - (start.tv_sec * 1000 * 1000 + start.tv_usec));
    free_bit_vector(pdata);
    getchar();
    return 0;
}


总结: 位运算应用场景还有很多,要想用好,主要看你的抽象能力。现在是大内存和多核时代,没有必要时也不建议使用,除非用在密集运算或需要高效率的算法上。