一、下面的公式将一个数的最右侧的'1'位变成'0'位,如果没有'1'位则生成所有位都为0的数:如 0010 1100 => 0010 1000
X & (X-1)
用这个公式可以判断一个数是否为2的幂(2n )如果X & (X-1)==0,说明X为2的幂。同理,可以用X & (X+1)判断X是否为2n-1的形式。
二、下面的公式析出一个数最右侧的1位,如果没有1位,则生成所有位都为0的数,如:1011 1010 => 0000 0010
X & (-X)
三、下面的公式析出一个数最右侧的0位,如果没有0位,则生成所有位都为0的数,如:1011 1011 => 0000 0100
~X & (X+1)
四、下面的三个公式可以识别后缀0的掩码,如果X=0则生成所有位都为1的数,如: 0101 1000 => 0000 0111
~X & (X-1) 或 ~(X | -X) 或 (X & -X) -1
五、下面的公式可以识别最右侧的1位和后缀0的掩码,如果X=0则生成所有位都为1的数,如: 0101 1000 => 0000 1111
~(X ^ (X-1)) (可以用同或表示,因为没有同或符号,只能转化成等价的异或表达)
六、下面的公式可以向右传播最右侧的1位,如果X=0则生成所有位都为1的数,如: 0101 1000 => 0101 1111
X | (X-1)
七、下面的公式可以将最右侧连续的1位串改成连续的0位串,如:0100 1100 => 0100 0000
( ( X | (X-1)) + 1) & X
对于j>k大于0,这个公式可以用来检测一个非负整数是否具有2j-2k的形式,使用之后对结果作0-检测。
八、上面的公式都具有对偶性,交换描述中的0和1,在公式中用X+1替换X-1,用X-1替换X+1,用~(X+1)替换-X,用|替换&,
用&替换|,X和~X不变,则可以得到一个新的正确的描述和表达式。
举个例子,第一个公式的对偶式为:
下面的公式将一个数的最右侧的0位变成1位,如果没有0位则生成所有位都为1的数,如:0100 1011 => 0100 1111
X | (X+1)
摘自:<<高效程序的奥秘>>