highbit和lowbit函数

highbit

    public static int highestOneBit(int var0) {
        var0 |= var0 >> 1;
        var0 |= var0 >> 2;
        var0 |= var0 >> 4;
        var0 |= var0 >> 8;
        var0 |= var0 >> 16;
        return var0 - (var0 >>> 1);
    }

1、第一步的作用是把最高位1右移移位,并与原数据按位取或。那么这就使得最高位和它的下一位是连续两个1。
2、第二步的作用是把刚刚移位得到连续两个1继续右移两位并与原数据按位取或。那么这就使得最高两位和它的下两个连续位组成四个连续的1。
3、 以此类推,最终得到的i是从开始的最高位到结束全是1。并减去i不带符号的右移一位,即可得到一个int数据的最高位的值。
4、上述情况是针对于i不为零和负数的情况,如果i为零,那么得到的结果始终为零。如果i位负数,那么得到的结果始终是-2147483648。即等于Integer.MIN_VALUE。(原因在于负数的最高位始终为1,即是负数的符号位)

调用Integer.highestOneBit即可调用此方法。

lowbit的概念

f=lowbit(x)

这个函数的值是x的二进制表达式中最低位的1所对应的值。

lowbit(6)因为(110)2中最低位(就是从右往左数的第二位)对应的数是2

所以假设一个数的二进制最低位的1在从右往左数的第k位,那么它的lowbit值就是

2^{k-1}

lowbit函数的实现

一、

x&(x^(x-1))

注意这个^是异或!

二、

    public static int lowestOneBit(int x) {
        return x & -x;
    }

我们得到lowbit的值,只需要得到最后一个1的位置,并且把除了这个位置之外的所有位置全部置成零。然后输出就可以。

根据计算机补码的性质:补码就是原码的反码加一。

比如6的二进制为110,反码为001,加一为010,110 & 010 = 010。

用lowbit运算统计1的个数

我们可以使用lowbit运算统计一个整数的二进制形式下1的个数。

原理:我们先用lowbit运算找出lowbit(x),然后用原数减去这个数,依次循环,直到为0为止。

这也是树状数组的实现原理。

代码:

while(x != 0){
    x-=x&-x;
    ans++;
}

树状数组

未完


   转载规则


《highbit和lowbit函数》 锦泉 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录