java if 中integer_Java源码分析:Integer中的位运算

Integer中用到了很多位运算,而java整数的固定长度也为位运算提供不少便利性,下面对Integer中的经典方法做分析(这些方法基本上都用到了位运算,原因很简单:高效,并行)

1.求整数中二进制1的个数

public static intbitCount(int i) {

// HD, Figure 5-2

i= i - ((i >>> 1) & 0x55555555);

i= (i & 0x33333333) + ((i >>> 2) & 0x33333333);

i= (i + (i >>> 4)) & 0x0f0f0f0f;

i= i + (i >>> 8);

i= i + (i >>> 16);

returni & 0x3f;

}

分析:该方法仅需五步完成,时间复杂度是O(logN)(N是整数的二进制长度),算法妙在二进制并行运算,之后的算法很多也用到了并行运算。

分解:

第一步:求每两位中1的个数之和,比如i=(01)( 11)( 00)( 10)( 11)( 01)( 11)(01)->(01)(10)(00)(01)(10)(01)(10)(01)

第二步:求前面结果的每四位之和(0110)(0001)(1001)(1001)->(0010)(0001)(0010)(0010)

第三步:同上道理,求每8位置和

。。。。

并行:比如求没两位之和时,不用先等前面两位算完再算后面两位,直接同时进行,这也是位运算一大特色

2.返回具有至多单个1 位的 int 值,在指定的 int 值中最高位(最左边)的 1 位的位置

public static inthighestOneBit(int i) {

// HD, Figure 3-1

i |= (i >>1);

i |= (i >>2);

i |= (i >>4);

i |= (i >>8);

i |= (i >> 16);

return i - (i >>> 1);

}

分析:该方法时间复杂度是O(logN)

分解:

第一步:让整数二进制最高位为1的右边一位也为1

第二步:让整数二进制最高位为1的右边3位也为1

第三步:让整数二进制最高位为1的右边7位也为1

。。。。

最后整数二进制最高位为1的右边全为1,然后通过运算只保留最高位的1

3.返回具有至多单个 1 位的 int 值,在指定的 int 值中最低位(最右边)的 1位的位置

public static intlowestOneBit(int i) {

// HD, Section 2-1

return i & -i;

}

分析:该方法一步完成,妙哉!

4.在指定 int 值的二进制补码表示形式中最高位(最左边)的 1 位之前,返回零位的数量

public static intnumberOfLeadingZeros(int i) {

// HD, Figure 5-6

if (i == 0)

return 32;

int n = 1;

if (i >>> 16 == 0) { n += 16;i <<= 16; }

if (i >>> 24 == 0) { n +=8; i <<=8; }

if (i >>> 28 == 0) { n +=4; i <<=4; }

if (i >>> 30 == 0) { n +=2; i <<=2; }

n -= i >>> 31;

return n;

}

分析:时间复杂度是O(logN),采用了类似二分查找的思想

5.返回指定的 int 值的二进制补码表示形式中最低(“最右”)的为 1 的位后面的零位个数

public static intnumberOfTrailingZeros(int i) {

// HD, Figure 5-14

inty;

if(i == 0) return 32;

intn = 31;

y= i <<16; if (y != 0) { n = n -16; i = y; }

y= i << 8; if (y != 0) { n = n - 8; i = y; }

y= i << 4; if (y != 0) { n = n - 4; i = y; }

y= i << 2; if (y != 0) { n = n - 2; i = y; }

returnn - ((i << 1) >>> 31);

}

分析:类似上一方法

6.反转二进制整数

public static intreverse(int i) {

// HD, Figure 7-1

i= (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;

i= (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;

i= (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;

i= (i << 24) | ((i & 0xff00) << 8) |

((i >>> 8) & 0xff00) | (i>>> 24);

returni;

}

分析:时间复杂度是O(logN),采用分治法,先局部后整体

分解:第一步:每相邻两位互换

第二步:每相邻四位互换,四位内部不互换

…..

7.获得整数征服符号表示:1,0,-1

public static intsignum(int i) {

// HD, Section 2-7

return (i >> 31) | (-i>>> 31);

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值