java最高位_java - 算法 - 求小于一个数字的二进制的最高位

看Integer源码的时候发现的= =感觉非常有意思。。。

public static int highestOneBit(inti) {//HD, Figure 3-1

i |= (i >> 1);

i|= (i >> 2);

i|= (i >> 4);

i|= (i >> 8);

i|= (i >> 16);return i - (i >>> 1);

}

核心算法就就是这个

i |= (i >> 1);

| 或运算 两个数字或运算只要其中一个的对应位是1那么结果为1

比如   1010 | 1001 = 1011

>> 右移 把数字的二进制向右位移,保留符号位(int最左位表示正负, 这里先不考虑负数情况)

比如

1010 >> 1    =    0101

1010 >> 2    =    0010

1010 换算为十进制为 10

0101 换算为十进制为 5

0010 换算为十进制为 2

不难看出= =右移的本质其实是除以2,多少位就是除以2的多少次幂。

首先int类型位数最大为16位,所以这里最大只右移了16位。

先按方法手动算一下

比如 0000 0000 1000 1110

i |= (i >> 1);

i >>1 = 0100 0111

1000 1110   |   0100 0111   =  1100 1111

i |= (i >> 2);  (此时i已经变成了 1100 1111)

i >>2 = 0011 0011

0011 0011  |  1100 1111 = 1111 1111

...

因为或算法只要有1个是1那么这位就是1,所以很容易得出

最后经过

i |= (i >> 1);

i |= (i >> 2);

i |= (i >> 4);

i |= (i >> 8);

i |= (i >> 16);

后   ( i 的最高位之后的所有位都会变成1)

i = 1111 1111;

然后执行最后一步

return i - (i >>> 1);

>>>也是右移,只不过不保留符号位,这样可以保证最后结果不受负数影响,这里先不考虑负数情况。

此时

i = 1111 1111;

i >>> 1  = 0111 1111

1111 1111 - 0111 1111 = 1000 0000 得到最高位。

所以这个算法的本质:

先把最高位右边的所有位都变成1

然后此时: 数字 - 数字右移1位 = 该整数二进制形式的最高位。

脑洞:可以不断左移一个数字直到这个数变成负数= = 然后也可以得到最高位是哪一位,虽说有点蠢= =

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值