位运算技巧
void swap(int* a, int* b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
// 有奇数个1返回1,有偶数个1返回0。
int check_bit(int n)
{
n ^= n >> 1;
n ^= n >> 2;
n ^= n >> 4;
n ^= n >> 8;
n ^= n >> 16;
return n & 1;
}
uint32_t method_1_uint32_popcount(uint32_t n)
{
n = (n & 0x55555555) + ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n & 0x0f0f0f0f) + ((n >> 4) & 0x0f0f0f0f);
n = (n & 0x00ff00ff) + ((n >> 8) & 0x00ff00ff);
n = (n & 0x0000ffff) + ((n >> 16) & 0x0000ffff);
return n;
}
uint32_t method_2_uint32_popcount(uint32_t n)
{
n = n - ((n >> 1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
n = (n + (n >> 4)) & 0x0f0f0f0f;
n = n + (n >> 8);
n = n + (n >> 16);
return n & 0x3f;
}
uint32_t method_3_uint32_popcount(uint32_t n)
{
n = n - ((n>>1) & 0x55555555);
n = (n & 0x33333333) + ((n >> 2) & 0x33333333);
return ((n + (n >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
#ifndef Q3_VM
#ifdef __linux__
assert( !isnan(y) ); // bk010122 - FPE?
#endif
#endif
return y;
}
n & ( n + 1 ) // 把右边连续的1变成0
n & ( n - 1 ) // 把右边第一个1变成0
n | ( n + 1 ) // 把右起第一个0变成1
n | ( n - 1 ) // 把右起连续的0变成1
n ^ ( n + 1 ) // 取右边连续的1
n & -n 或 n & ( n ^ ( n - 1 ) ) // 去掉右起第一个1的左边
( n << x ) | ( x >> ( 32 - x ) ) // 高低位交换,前x位
( n ^ (n >> 31) ) - (n >> 31) // 有符号整数计算绝对值