位操作技巧
本文发布于游戏程序员刘宇的个人博客,长期更新,转载请注明源地址https://www.cnblogs.com/xiaohutu/p/10951911.html
需要补充或者修改的请留言~
1. 取第n位的值(从右边)
int r = (v >> n) & 1;
2.把某一位置1(从右边)
v = v | (1 << n);
3.把某一位取反(从右边)
v = v ^ (1 << n);
4.把最后一个1置0
v = v & (v - 1);
5.把最后一个0置1
v = v | (v + 1);
6.奇偶判断
(v & 1)
7.计算绝对值
int a = v >> 31;
int r = (v ^ a) - a;
或者 int r = (v + a) ^ a;
8. 取模
//v % (2^n)可以转化为去掉n位之前的值
int mod = v & (2^n - 1);
9.乘2的n次方
int r = v << n;
10.除2的n次方
int r = v >> n;
11.除2的余
int r = v & 1;
12. 判断语句 v == a ? b : a;
v = a ^ b ^ v;
13.a与b互换
void swap(int& x , int& y)
{
x ^= y;
y ^= x;
x ^= y;
}
14.否为2的幂
bool power2(int v)
{
return ((v & (v - 1)) == 0) && (v != 0);
}
15,求整数的平均值
int average(int x, int y)
{
return (x & y) + ((x ^ y) >> 1);
}
16.取v的符号
int v;
int sign;
//返回-1或0
sign = -(v < 0);
sign = v >> (sizeof(int) * CHAR_BIT - 1);
//返回-1或+1
sign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1);
//返回-1,0,1
sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1));
sign = (v > 0) - (v < 0);
17.判断两数符号是否相反
bool f = ((a ^ b) < 0);
18.没有分支语句的min或者max函数
//min(a,b)
int r = b ^ ((a ^ b) & -(a < b));
//max(a,b)
int r = a ^ ((a ^ b) & -(a < b));
19.是否取反(不带判断语句)
bool negative;
int r = (v ^ -negative) + negative;
20.根据掩码mask合并a和b, mask为1的位为b的值,反之为a的值
unsigned int r = a ^ ((a ^ b) & mask);
21.计算二进制v中1的个数n
unsigned int v;
unsigned int n;
for (n = 0; v; n++)
v &= v - 1
22.二进制位反转
unsigned int reverse(register unsigned int x) { x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); return((x >> 16) | (x << 16));
}
22.二进制位反转2
unsigned int
reverse(register unsigned int x)
{
register unsigned int y = 0x55555555;
x = (((x >> 1) & y) | ((x & y) << 1));
y = 0x33333333;
x = (((x >> 2) & y) | ((x & y) << 2));
y = 0x0f0f0f0f;
x = (((x >> 4) & y) | ((x & y) << 4));
y = 0x00ff00ff;
x = (((x >> 8) & y) | ((x & y) << 8));
return((x >> 16) | (x << 16));
}
23.浮点数与0的判断
#define FasI(f) (*((int *) &(f)))
#define FasUI(f) (*((unsigned int *) &(f)))
#define lt0(f) (FasUI(f) > 0x80000000U)
#define le0(f) (FasI(f) <= 0)
#define gt0(f) (FasI(f) > 0)
#define ge0(f) (FasUI(f) <= 0x80000000U)
24.下一个2的幂次方
unsigned int nextpowerof2(register unsigned int x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return(x+1);
}
24.保留最高位的1 (上一个2的幂次方)
unsigned int lastpowerof2(register unsigned int x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return(x & ~(x >> 1));
}