Java源码解释之Integer.bitCount
Java中的Integer.bitCount(i)的返回值是i的二进制表示中1的个数。源码如下:
public static int bitCount(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);
return i & 0x3f;
}
源码解析如下:

public static int bitCount(int i) {
// HD, Figure 5-2
/**
* 每两位为一个单元,把原来单元中1的个数储存在原来的单元中
*/
i = i - ((i >>> 1) & 0x55555555);
/**
*0x33333333其实就是二进制……00110011(共32位),因为上面的每两位代表1的个数,所以下面的这几行就是要把上面每两位
* 的数字加起来,下面的这行代码可以这样理解,每4位分为一组,然后4位中的每两位相加,相加的结果在储存到这4位二进制数中,
* i & 0x33333333表示每4位中的低2位,(i >>> 2) & 0x33333333表示每4位中的高2位,然后在相加
*/
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
/**
* 这个更好理解,i >>> 4表示往右移动了4位,然后在与i相加,相当于每8位一组,然后8位中的高4位与低4位相加储存在低4位中,
* 然后这里在与0x0f0f0f0f进行与运算,把高4位完全置为0了,因为0x0f0f0f0f用二进制表示就是00001111000011110000111100001111,
* 看到这里可能有些困惑,这里为什么要与0x0f0f0f0f进行与运算,因为每8位一组的话,最多也就是8,那么4位数足够了,高4位就没有必要了,
* 如果不置为0有没有影响,其实如果1的位数极少的话是没什么影响的,但如果1的位数比较多到后面计算的结果可能就会往前进位,导致结果错误,
* 所以这一步要进行一次与运算,那为什么上面的那行代码没有把4位一组中的高两位置0,这是因为4位一组最多有4个1,而2位二进制数最多表示3,
* 小于4,所以不能置为0,
*
*/
i = (i + (i >>> 4)) & 0x0f0f0f0f;
/**
* 和上面类似,每16位分为一组,每组中的高8位和低8位相加,这里的代码相加的很干净,因为无论是高8位还是低8位中的前4位在上面一行中
* 都已经置为0了,这里也可以像上面那样,加完之后在与0x00ff00ff进行与运算,但其实这里已经没有必要了,因为int类型为32位,
* 最多也就32个1,用8位数储存足够了,所以不会超过8位,也就不用担心超过8位在往前进1位的问题了。
*/
i = i + (i >>> 8);
/**
* 和上面类似,就不在详述
*/
i = i + (i >>> 16);
/**
* 到最后为什么要和0x3f进行与运算,0x3f用二进制表示就是111111,因为上面两行没有进行与运算,所以前面的数据都是无效的,
* 只有最后8位是有效的,而后8位的前两位不用说肯定为0,因为最多也就32个1,用后面6位数表示就已经足够了,所以这里与0x3f
* 进行与运算,来计算出最终1的个数
*/
return i & 0x3f;
}
i=031bi
Java源码解释之Integer.bitCount的更多相关文章
- JDK源码学习笔记——Integer
一.类定义 public final class Integer extends Number implements Comparable<Integer> 二.属性 private fi ...
- 从Java源码到Java字节码
Java最主流的源码编译器,javac,基本上不对代码做优化,只会做少量由Java语言规范要求或推荐的优化:也不做任何混淆,包括名字混淆或控制流混淆这些都不做.这使得javac生成的代码能很好的维持与 ...
- java源码——0~9十个数字不重复地使用使加法表达式成立
这个问题是在我写个的几个博客里较为复杂的一个.首先,先看看整个问题的表述. 星号表示0~9的一个数字,而且不允许重复,使得下面的加法表达式成立.输出所有结果. ※ ※ ※ ※ ※ + 2 ...
- Java源码分析 | CharSequence
本文基于 OracleJDK 11, HotSpot 虚拟机. CharSequence 定义 CharSequence 是 java.lang 包下的一个接口,是 char 值的可读序列, 即其本身 ...
- 解密随机数生成器(二)——从java源码看线性同余算法
Random Java中的Random类生成的是伪随机数,使用的是48-bit的种子,然后调用一个linear congruential formula线性同余方程(Donald Knuth的编程艺术 ...
- Java源码解读(一)——HashMap
HashMap作为常用的一种数据结构,阅读源码去了解其底层的实现是十分有必要的.在这里也分享自己阅读源码遇到的困难以及自己的思考. HashMap的源码介绍已经有许许多多的博客,这里只记录了一些我看源 ...
- 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法
注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...
- 24点扑克牌游戏——(含java源码)(GUI实现)
给出四个数字,要求,在其间添加运算符和括号,使得计算结果等于24. 括号的放置即为决定哪几个数先进行计算.所以,我们先确定首先进行计算的两个相邻的数,计算完成后,就相当于剩下三个数字,仍需要在它们之间 ...
- Java源码——String
最近在研究java的源代码,但是由于自己英语水平有限,所以想使用中文注释的方式把源码里的方法全部重写 一遍,下面是楼主整理出来的一小部分.我把整体的项目托管到GitHub上了,欢迎大家前去交流学习. ...
随机推荐
- Check the difficulty of problems - poj 2151 (概率+DP)
有 T(1<T<=1000) 支队伍和 M(0<M<=30) 个题目,已知每支队伍 i 解决每道题目 j 的的概率 p[i][j],现在问:每支队伍至少解决一道题,且解题最多的 ...
- storm 错误汇总
https://blog.csdn.net/xiaolang85/article/details/38492277
- 【学习ATX基于uiautomator2】之API操作Android方法
具体API可参考:<uiautomator2>以及参考github官方文档 感谢:Ricky_Frog <Python+uiautomator2手机UI自动化测试实战 -- 2. 用 ...
- iframe宽高百分百显示
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- weblogic配置oracle数据源
在weblogic配置oracle数据源还是挺简单的,网上也有很多关于这方面的文章,写给自己也写给能够得到帮助的人吧.weblogic新建域那些的就不说了哈.点击startWebLogic文件,会弹出 ...
- Linux文件的打包与压缩
打包命令: tar tar 的选项与参数非常的多!我们只讲几个常用的选项,更多选项您可以自行 man tar 查询罗! [root@www ~]# tar [-j|-z] [cv] [-f 创建的档名 ...
- VC中怎么输入特殊符号(如平方、立方等下标符号)
同在列表控件里显示汉字一样,直接把输入法里特殊字符放进一个数组里,然后再赋值:CString F[]={"m²","∑","±"," ...
- TArray数组
TArray<int32> arr; arr.Init(,); ; index < arr.Num(); index++) { FString str = FString(" ...
- node读写Excel操作
目支持写Excel的node.js模块: node-xlsx: 基于Node.js解析excel文件数据及生成excel文件: excel-parser: 基于Node.js解析excel文件数据,支 ...
- 监视EF生成SQL的方法(log , SqlServerProfile)
大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...