- bitCount
public static int bitCount(int i);返回int的 二进制 数中1的数量,源码如下:
这个方法很有意思,解法如下:
简单的描述这个方法的逻辑就是,
第一步:每2位一组,分组算出1的个数
第二步:每4位一组,分组算出1的个数
第三步:每8位一组,分组算出1的个数
第四步:每16位一组,分组算出1的个数
第五步:全部(32位)一起算出1的个数
第六步:去掉无用位,返回结果
最后一步:
举例详解:
先看下0x55555555、0x33333333、0x0f0f0f0f对应的二进制
0x55555555 = 01010101010101010101010101010101 0x33333333 = 00110011001100110011001100110011 0x0f0f0f0f = 00001111000011110000111100001111 0x3f = 00000000 00000000 00000000 00111111
举例一个数i的二进制为:00110101 10110001 00010001 00001111
第一步:每2位一组,分组算出1的个数
首先i>>>1 = 00011010 11011000 10001000 10000111 //二进制右移动一位,高位补0 然后((i >>> 1) & 0x55555555) = 00010000 01010000 00000000 00000101 //计算出原i的奇数为上1的个数(结果为0或1) 最后i - ((i >>> 1) & 0x55555555) = 00100101 01100001 00010001 00001010 //计算出每两位上的i的个数(从左到右,2位一组,结果位0(00)或1(01)或2(10))
第二步:每4位一组,分组算出1的个数 (以第一步的结果来计算)
首先i & 0x33333333 = 00100001 00100001 00010001 00000010 //对第一步结果 每四位一组,计算出每四位的后两位的1的个数 其次 i >>> 2 = 00001001 01011000 01000100 01000010 //第一步的结果右移两位 然后 ((i >>> 2) & 0x33333333) = 00000001 00010000 00000000 00000010 //对第一步结果 每四位一组,计算出每四位的前两位的1的个数 最后 (i & 0x33333333) + ((i >>> 2) & 0x33333333) = 00100010 00110001 00010001 00000100 //每四位一组,计算出每四位里1的个数
第三步:每8位一组,分组算出1的个数(以第二步的结果来计算)
首先i >>> 4 = 00000010 00100011 00010001 00010000 //对第二步结果 右移4位 其次(i + (i >>> 4)) & 0x0f0f0f0f 可以分解为 i & 0x0f0f0f0f + (i >>> 4) & 0x0f0f0f0f //对第二步结果 每八为一组 分别计算出每八位的前四位和后四位的1的个数,然后相加得出每八位的1的个数 i & 0x0f0f0f0f = 00000010 00000001 00000001 00000100 //每八位后四位1的个数 (i >>> 4) & 0x0f0f0f0f = 00000010 00000011 00000001 00000000 // 每八位前四位的1个数 i & 0x0f0f0f0f + (i >>> 4) & 0x0f0f0f0f = 00000100 00000100 00000010 00000100 //每八位1的个数,这里可以注意到每八位1的数量都用后四位表示出来了
第四步:每16位一组,分组算出1的个数(以第三步的结果来计算)
首先 i >>> 8 = 00000000 00000100 00000100 00000010 //第三步的结果右移8位 然后 i + (i >>> 8) = 00000100 00001000 00000110 00000110 //这里我们可以注意到每16位的后8位其实就是这16位1的个数,前8位无用,后面会消去
第五步:全部(32位)一起算出1的个数(以第四步的结果来计算)
首先 i >>> 16 = 00000000 00000000 00000100 00001000 //对第四步结果右移16位 其次 i + (i >>> 16) = 00000100 00001000 00001010 00001110 //这里我们注意到是把第四步结果的第一个16位和第2个16位的后八位相加, //得到所有的1的个数,前面24位其实都无用
第六步:去掉无用位,返回结果
i & 0x3f = 00000000 00000000 00000000 00001110
所以最后二 进制 00110101 10110001 00010001 00001111的1的个数为:14
总结:取二进制里1的个数方法有很多,但这里实现的很奇妙,思路很奇特,不愧是大师们的杰作
- decode
把String字符解码成Integer数字,0x和#开头处理成16进制,0开头处理成8进制,其它为10进制
- toUnsigned long :返回无符号long类型转换的数值
- divideUnsigned:返回 无符号整数 整除的商
- remainderUnsigned:返回无符号整数整除的余数
- formatUnsignedInt:将数字转换为字符数据存放在字符buf中
- getInteger:
public static Integer getInteger(String nm) public static Integer getInteger(String nm, int val) public static Integer getInteger(String nm, Integer val) 最后用System.getProperty()和Integer.decode()实现
- lowestOneBit
public static int lowestOneBit(int i);返回对应二进制最低位为1的位置
- highestOneBit
public static int highestOneBit(int i);返回最高位为1的位置
- max、min:利用Math的max和min函数取较大和较小的数字
- rotateLeft、rotateRight循环左移(将移出高的位放到该数的低位)、右移(将移出的低位放到该数的高位)