1.统计整数二进制中比特1数目(redis bitcount命令):
int countNumberbit1(int x)
{
x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
x = (x & 0x0000FFFF) + ((x >> 16) & 0x0000FFFF);
return x;
}
2.获得第一个大于size且满足2的n次方的整数(常用于计算哈希表大小)
unit32_t next_power_size(uint32_t nSize)
{
nSize -= 1;
nSize |= (nSize >> 1);
nSize |= (nSize >> 2);
nSize |= (nSize >> 4);
nSize |= (nSize >> 8);
nSize |= (nSize >> 16);
return nSize + 1;
}
3.二进制翻转
uint32_t bitReverse(uint32_t v)
{
v = ((v >> 1) & 0x55555555) | ((v << 1) & 0xaaaaaaaa);
v = ((v >> 2) & 0x33333333) | ((v << 2) & 0xcccccccc);
v = ((v >> 4) & 0x0f0f0f0f) | ((v << 4) & 0xf0f0f0f0);
v = ((v >> 8) & 0x00ff00ff) | ((v << 8) & 0xff00ff00);
v = ((v >> 16) & 0x0000ffff) | ((v << 16) & 0xffff0000);
return v;
redis dictscan原生代码:
static unsigned long rev(unsigned long v)
{
unsigned long s = 8 * sizeof(v); // bit size; must be power of 2
unsigned long mask = ~0;
while ((s >>= 1) > 0) {
mask ^= (mask << s);
v = ((v >> s) & mask) | ((v << s) & ~mask);
}
return v;
}
4.计算二进制最高位为1的位置(PHP7原生代码)
//size最大值为3072
/* higher set bit number (0->N/A, 1->1, 2->2, 4->3, 8->4, 127->7, 128->8 etc) */
static zend_always_inline int zend_mm_small_size_to_bit(int size)
{
int n = 16;
if (size <= 0x00ff) {n -= 8; size = size << 8;}
if (size <= 0x0fff) {n -= 4; size = size << 4;}
if (size <= 0x3fff) {n -= 2; size = size << 2;}
if (size <= 0x7fff) {n -= 1;}
return n;
}
5.从低到高,计算第一比特0的位置(PHP7原生代码)
static zend_always_inline int zend_mm_bitset_nts(zend_mm_bitset bitset)
{
n = 0;
if (sizeof(zend_mm_bitset) == 8) {
if ((bitset & 0xffffffff) == 0xffffffff) {n += 32; bitset = bitset >> Z_UL(32);}
}
if ((bitset & 0x0000ffff) == 0x0000ffff) {n += 16; bitset = bitset >> 16;}
if ((bitset & 0x000000ff) == 0x000000ff) {n += 8; bitset = bitset >> 8;}
if ((bitset & 0x0000000f) == 0x0000000f) {n += 4; bitset = bitset >> 4;}
if ((bitset & 0x00000003) == 0x00000003) {n += 2; bitset = bitset >> 2;}
return n + (bitset & 1);
}