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++;
}
树状数组
未完