位操作是一種靈活、強大的編程技巧。
最簡單的使用場景,是將多個字段壓到一個字段中,這樣可以使用更少的交互來傳遞更多的內容。
這在LBA編址上很常見,如一個LBA應該編碼進去lunId, poolId, 是否壓縮,lun中邏輯地址。
也常用在信息收發上:如socket中的包頭,將多種信息壓縮到一個頭中一次收發。
此處需要注意的是位的偏移長度,以及在實現的時候需要注意將每個字段強轉爲待壓字段的長度單位。
還有一些不太常用的但是很有意思的,記錄一下,說不定哪天就能提供一個更好的思路:
//返回val中二進制位裏1的個數:
int findBitOnesCount(int val){
int cnt = 0;
while(val){
cnt++;
value = value &(value-1);
}
return cnt;
}
//使用一個bitmap來表示是node_id的添加、刪除,查詢是否在其中:
int node_set;
int add_node_to_node_set(node_set,node_id){
return node_set | (1 << node_id);
}
int remove_node_from_node_set(node_set,node_id){
return node_set & ~(1<<node+id);
}
bool is_node_in_node_set(node_set,node_id){
return ((node_set &(1<<node_id))!=0);
}
//給定一個數,找到下一個離該數最近的2的n次方的數字。常用於設定一個一致性哈希算法的mod的值
int next_power_of_two(int num){
num--;
num |= num >> 1;
num |= num >> 2;
num |= num >> 4;
num |= num >> 8;
num |= num >> 16;
num++;
return num;
}
//要生成一個環的時候,則可以這樣來做:
已知可能有n個對象,我們想要將其圍成一個環。
先獲得離n最近的大於n的2的次方的數字ring_size,根據上方的方式來獲得;
獲得ring_mask = ring_size - 1;
然後在添加x到環中(x可以爲任何數)時,可以:
ring[x & ring_mask] = n;