第2章
2.1 操作最右边的位元
x&(x - 1)
作用1:将字组中值为1且最靠右边的位元变为0,没有1结果就是0。(例如:0101 1110[最靠右边的1是倒数第二位] => 0101 1100,0101 0001[最靠右边的1是倒数第一位] => 0101 0000)。其他位置数据变更不确定
作用2:判断无符号整数x是否是2的幂或0,运行之后的结果为0说明x = 2^n 或 0。例子:
2(10)&1(01) = 0,4(100)&3(011)=0,16(10000) &15(01111) = 0
x | (x + 1)
作用:将字组中值为0且最靠右边的位元变为1,没有0,结果都是1,(例如:1010 0111 [最靠右边的是顺数第5位] => 1010 1111, 1010 0001[最靠右边的是倒数第二位] => 1010 0011,1010 1111 => 1011 1111)。也可以理解为从右往左数,将第一个为0的位转为1。
x&(x + 1)
作用: 将x字组尾部的连续一组1变成0,如果尾部没有1,值不变。
例子:
1010 0111[尾部有3个1] & 1010 1000 => 1010 0000[尾部3个1全部变为0]
1010 0110[尾部没有1] & 1010 0111 => 1010 0110[不变]
x | (x - 1)
**作用:**将x字组尾部的连续一组0变成1,尾部没有0,值不变。
例子:
1010 0100[尾部3个0] | 1010 0011 => 1010 0111[尾部3个0全部变为1]
1010 0111[尾部没有0] | 1010 0110 => 1010 0111[不变]
~x&(x + 1)
作用: 将x中最靠右且值为0的位元变为1,并将其余位置0。如果x中没有值为0的位元,结果为0。
例子:x = 1010 0111 最靠右的0为第5位。
~x & (x + 1) => ~1010 0111 & (1010 0111 + 1) => 0101 1000 & (1010 1000) => 0000 1000,x顺数第5位的0变为1,其余位为0。
~x | (x -1)
作用: 将x最靠右且值为1的位元变为0,其余位置变为1。
例子:x = 1010 1000 最靠右的1为顺数第5位
~x | (x - 1) = ~1010 1000 | (1010 1000 - 1) => 0101 0111 | 1010 0111 => 1111 0111
x&(x - 1)、(x | -x)、(x & -x) -1
作用:将字组尾部所有值为0的位元全都变成1,其余位元设为0。没有值为0的位元,结果为0
例子: 0101 1000[尾部3个0] => 0000 0111
~x | (x + 1)
作用: 将字组尾部所有值为1的位元全都变成0,其余位设为1。没有1的位元,运算结果都为1。
例子: 1010 0111 => 1111 1000
x & (-x)
作用:保留字组中最靠右且值为1的位元,并将其余位置置0。x不存在1位元,运算结果为0。
例子: 0101 1000 => 0000 1000
x ^ (x - 1)
作用: 以最靠右且值为1的位元做分割点,分割点右边值为0的位元全部设成1,分割点左边全部设成0。没有值为1的位元,运算结果每一位都是1。尾部没有值为0的位元,值为1。因为只剩下分割点,并且分割点在最后一位。
例子: 0101 1000[分割点为顺数第5位] => 0000 1111
x ^ (x + 1)
作用: 将字组最靠右且值为0的位元,及其右方所有值为1的位元都设为1,左方位元全设为0,x没有值为0的位元,运算结果的每一位都是1,x的尾部没有值为1的位元时,运算结果为1。分割点为最靠近右边的0,运算的时候将分割点和分割点右边的位元设为1,分割点左边的位元设为0。
例子: 0101 0111[分割点顺数第5位] => 0000 1111
((x|(x -1)) + 1)& x)、((x & -x) + x) & x
作用: 将字组右侧连续出现且值为1的位元设为0,如果x是非负数,使用该公式运算结果为0,说明x = 2 ^ j - 2 ^ k形式, j >= k >= 0。
例子: 0101 1100 [顺数第4 - 6位为连续的1] => 0100 0000