计算机位运算
学习来自 http://graphics.stanford.edu/~seander/bithacks.html
取符号
int v = -5;
int sign;
sign = v >> (sizeof(int) * 8 - 1); 这里主要是将符号位进行了扩展,得到的是0xffffffff =-1
sign = +1 | (v >> (sizeof(int) * 8 - 1)); // if v < 0 返回 -1, 否则返回 +1
返回两个数的最大值和最小值
int x; // we want to find the minimum of x and y
int y;
int r; // the result goes here
r = y ^ ((x ^ y) & -(x < y)); // min(x, y)
r = x ^ ((x ^ y) & -(x < y)); // max(x, y)
这个是可以证明的,if x<y then r = y ^ ((x ^ y) & -1)
r =y^(x^y) =x
判断一个数是否是2 的幂
unsigned int v = 16;
bool r;
r = (v&(v-1))==0;
printf("the sign is %d\n", r); //这里输出的是1,因为16是2的幂。
分析如下:因为如果v
是2的倍数,那么他的值可能是0x00,0x02,0x04,0x08,0x10,.......
一旦发生了v-1
,那么很明显这个v和v-1就没有重合的了,他们相与的结果就只能等于0.
Note that 0 is incorrectly considered a power of 2 here. To remedy this, use:
f = v && !(v & (v - 1)); 若v=0 则f =0;若v=2,
这个程序并不好。 如果出现了v=0,还是单独考虑吧。
里面有太多的关于位操作的奇淫技巧,留着以后慢慢学习。