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上了,欢迎大家前去交流学习. ...
随机推荐
- 关于selenium IDE找不到元素bug
使用 selenium IDE 录制脚本,经常会发生 这样一种错误. 页面上,明明存在这个元素,就是找不到. 其实原理很简单 , 按钮 点击,没有时间延迟,但是页面加载,需要一段时间. 页面元素还 ...
- easyui换主题,并记录在cookie
首先将easyui的样式文件加入一个ID,这里命名为easyuiTheme,然后在样式文件下面加入一个JS文件 <script type="text/javascript" ...
- ASP.NET控件属性大全
ASP.NET控件属性大全 DataGridView 控件DataGridView 控件提供用来显示数据的可自定义表.使用 DataGridView 类,可以自定义单元格.行.列和边框. 注意Data ...
- 几款 ping tcping 工具总结
本文转载至:http://www.cnblogs.com/kerrycode/p/8092942.html ping 命令以前是一个很好用并且常用的网络测试工具,它是基于 ICMP 协议,但是出于网络 ...
- Stanford CoreNLP 3.6.0 中文指代消解模块调用失败的解决方案
当前中文指代消解领域比较活跃的研究者是Chen和Vincent Ng,这两个人近两年在AAAI2014, 2015发了一些相关的文章,研究领域跨越零指代.代词指代.名词指代等,方法也不是很复杂,集中于 ...
- 读写app.config AppSettings,保留注释与不保留注释
不保留 using System; using System.Configuration; namespace ConsoleApplication1 { class Program { static ...
- mac 干掉Dashboard
打开终端,输入下面的命令: defaults write com.apple.dashboard mcx-disabled -boolean YES 然后再重启一下 Dock,在终端输入 kill ...
- php检测非法字符方法
检测非法字符: [第一种]: 自己搞来玩的... 简单测试了下...暂无发现什么问题...日后再多测试下....日后再更>>>
- Amazon Virtual Private Cloud(虚拟专有网络)官方文档通读
一.什么是Amazon VPC? 参考资料: 官网文档 https://docs.aws.amazon.com/zh_cn/AmazonVPC/latest/UserGuide/VPC_Introdu ...
- 面试STAR法则
昨天投了几家公司的简历,A公司还没看简历,B公司没有通过简历,另外的后说(其实只投了这两家),B公司最终给了蛮中肯的回复: 虽然,一开始看到这样的结果,有些失落,仔细看过回复后,有些不屑和好奇.百度了 ...