一些有用的位操作技巧。主要来自 Bit Twiddling Hacks

# 符号操作

# 获取整数的符号

对于整数 v , 其符号 sign 可以用如下方式计算:

int v;      // we want to find the sign of v
int sign;   // the result goes here 
// CHAR_BIT is the number of bits per byte (normally 8).
sign = -(v < 0);  // if v < 0 then -1, else 0. 
// or, to avoid branching on CPUs with flag registers (IA32):
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));
// or, for one less instruction (but not portable):
sign = v >> (sizeof(int) * CHAR_BIT - 1);

如果希望结果 sign1-1 , 那么可以采用:

sign = +1|(v>>(sizeof(int) * CHAR_BIT - 1)); // if v<0 then -1, else 1

如果希望结果为 -1 , 01 , 那么可以采用:

符号 = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); 
sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1)); //-1、0 or +1, 速度高,可移植性差
sign = (v > 0) - (v < 0); //-1、0 or +1, 简洁

若希望得知非负性,即结果为 +10 , 那么可以采用:

sign = 1 ^ ((unsigned int)v >> (sizeof(int) * CHAR_BIT - 1))

上述所有的符号判断操作,底层都是基于数字符号位的获取。

# 检测两个整数是否符号相反

希望检测两整数读好相反,可以采用下述代码。其当且仅当符号相反时 bool f = true , 否则为 false .

int x, y; // input
bool f = ((x ^ y) < 0);

# 值计算

# 绝对值

如果希望得到整数 v 的绝对值,那么可以采用

int v; // input
unsigned int r; // result
int const mask = v>>sizeof(int)*CHAR_BIT - 1;
r = (v + mask)^mask;

# 值交换

借助加减法的值交换

#define SWAP(a,b) ((&(a)==&(b)) || \((a)-=(b),((b)+=(a)), ((a)=(b)-(a))))

# lowbit

#define LOWBIT(x) ((x)&(-(x)))