位运算符n&(n-1)详解与妙用

用处一:求一个int类型数是否为2的幂

 

1、当n=4时,二进制为:0100

      n-1=3,二进制为:0011

      则:n&(n-1)==0  解释(将0100最右边的1变为0 则 0000=0)

2、当n=8时,为1000

  n-1=7,为0111

  则n&(n-1)==0

3、当n=5,为0101

  n-1为0100

  则n&(n-1)=0100=4!=0  解释(将0101最右边的1变为0 则 0100=4)

从上面我们可以看出,凡是2的幂,均是二进制数的某一高位为1,且仅此高位为1,比如4,0100;8,1000。那么它的n-1就变成了1所处的高位变成0,剩余低位变成1,如4-1,0011,8-1,0111,那么n&(n-1)必为0

也就是n&(n-1)==0

用处二:一个数的二进制中有多少位为1

    function findNumberOf1(num) {
        var count = 0;
        var n = num;
        while(n!==0) {
            count++;
            n = (n-1)&n
            console.log('count',count)
            console.log('n',n)
        }
        console.log(count)
    }

    findNumberOf1(7)// 3

用处三:一个数是否为4的幂

一个数是4的幂,那么必然是2的幂,反之,则不然

那么首先确定条件n&(n-1)==0,确定出该数是否为2的幂,这就找到了一项必要条件

刚才说了一个数是2的幂却不一定是4的幂,比如2,8,32等这些都是2的级数次方

但是,我们可以发现,2的偶数次方,比如2^0=1,2^2=4,2^4=16,这些数减去1,都能被3整除,而2的奇数次方的数减去1之后无法被3整除,不信可以试试

这样的话,我们就可以很容易找到4的幂的充要条件,即 n>0 && ((n&(n-1))==0) && ((n-1)%3==0)

用处四:接下来还有一些可以用到符号&运算的例子,比如求一个数32位二进制的倒序

int result =0forint i=0;i<32;i++){

       result<<=1;//result先左移一位,低位补0

       result = result+(n&1);

     n>>=1;//n右移一位,高位补0

}

用处五:将一个数表示为16进制,并返回相应字符串

if(n==0) return "0";

String  result ="";

String[] map={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

while(n!=0){

result = map[n&15]+result;

n>>=4;

}

posted @ 2021-12-21 15:02  菜鸟小何  阅读(3404)  评论(0编辑  收藏  举报