位運算有很大的妙用,在C語言中發揚光大。有什麼做用呢?在數據結構和算法中有個很重要的概念就是:時間和空間。位運算就能夠提升時間的效率和空間的利用率。算法
沒有什麼神奇之處,只是以緊湊的二進制格式來描述數據結構,應用之多舉不勝舉。記住,最小的存儲單元是bit而不是byte數據結構
根本緣由是讀取內存次數少,咱們知道CPU一次讀取內存的最大字節數和字長有關,正是由於把數據壓縮在有限的數據結構中,讀取內存的次數大大減小。數據結構和算法
一、如何不使用中間變量,交換兩個變量? ide
a = a ^ b; b = a ^ b; a = a ^ b;
可能會有人說使用加減法也能夠,如:測試
a = a + b; b = a - b; a = a - b;
可是加減法是有反作用的,容易致使數據溢出。spa
二、狀態的改變,咱們可能常常寫相似下面的代碼:內存
if (b) { b = false; } else { b = true; }
或者更精簡一點get
b = b ? false : true;
但依然會彆扭,由於你要改變一個標誌的狀態,首先要知道原有狀態,使用位運算能夠避免it
b ^= b;
三、位向量,不少底層庫中都有位向量的類,可用於不少場合,高效環保。我本身寫了一個位向量,求解1億一下素數,時間不到3秒,內存佔用不到13M,可見位運算的威力。io
#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; }
總結: 位運算應用場景還有不少,要想用好,主要看你的抽象能力。如今是大內存和多核時代,沒有必要時也不建議使用,除非用在密集運算或須要高效率的算法上。