不知道上一篇文章看的怎么样了:惧怕面试被问HashMap?这一篇就搞定了!
在这篇文章中,我比较详细的分析了为何HashMap的初始化容量是16以及为何容量的大小要是2的整数次幂!java
不知道你看懂了没,若是你看的懵懵懂懂的话,我猜你对如下基础知识必定不那么熟悉:web
怎么样,对这些基础知识掌握的如何,这些能够说都是大学时候学的计算机基础了,不过,我知道你当时确定没学会,即便学会了也忘得差很少了。面试
其实吧,这些基础知识真的超级重要,你看,如今阅读源码的时候由于这些基础知识不过关而遇到坎了吧。算法
别担忧,今天我们一块儿越过这道坎!数据结构
对于进制转换这个啊,说来惭愧,我以前学过不止一次,曾经有一次还花了很长时间,作笔记,画图,弄了满满的一张A4纸,当时以为对进制转换这块彻底OK了,之后不再怕进制转换了。并发
但是嘞后来读源码的时候遇到进制转换的时候仍是以为不知所措,发现以前学的都忘得差很少了,唉。app
因此啊,对于学习,咱们可不能一味的向前学习新知识,对于以前的知识也要常常回顾,温故而知新,能够为师矣嘛工具
好啦,我们此次再来一块儿学习下进制转换吧!学习
对于进制转换啊,其实咱们的重点主要放在与十进制之间的各类转换便可,由于这才是咱们日常使用频率比较高的,因此要优先熟练的掌握这些。网站
十进制咱们再熟悉不过了,那啥是二进制嘞,简单来讲,二进制就是用0和1来表示的数值,在十进制中逢十进一,借一当十,而二进制呢?那就是逢二进一,借一当二,这个好懂,可是这里我要说些概念。
什么嘞?后面咱们要说到原码,反码和补码,这里先说下,它们都是二进制数,也就是都是由0和1表示的,单是可能具体的数值不同。
咱们要知道,对于计算机而言,它只认识0和1,因此对于数据在计算机中的存储都是以二进制的形式来存储的,好了,先有这个概念。
先来看一个图:
再看进位产生的二进制对应的十进制是否是这些数值:
2,4,8,16……
那么你看这些产生进位的二进制数值有什么特色,是否是最高位(最左边)是否是都是1,其余都是0,因此这里就有个规律:
十进制下的2的整数次幂的数的二进制的高位都是1,其余全是0,而后看是2的几回幂,是几就有几个零
好吧,我相信这里没什么难理解的!
ps:看到这里你是否是更容易理解为何HashMap的容量要是2的整数次幂了呢?
那么二进制的数据怎么转换成十进制呢?咱们看十进制的11从右往左是否是依次表明1个1,1个10,加起来也就是11.
那么来看二进制1011怎么表示,看下面的:
二进制的数从右向左各个位表示十进制的含义:
第一个1表示:1的个数(有1个1)
第二个1表示:2的个数(有1个2)
第三个0表示:4的个数(有0个4)
第四个1表示:8的个数(有1个8)
为何是1(默认右边第一位开始),2,4,8呢?注意上面说的那个规律,因此上面的加起来就是1+2+0+8等于11。
怎么样?二进制转十进制是否是比较简单,其实后面还有个公式,等下再说,咱们继续往下看
知道吗?这里有个通用的方法那就是:除以2,余数逆序排列,看个例子吧:
咱们以前就说过,对于进制转换咱们重点关注的就是与十进制之间的转换,咱们上面介绍了二进制和十进制之间的互相转换,那么还有八进制和十六进制,它们与十进制之间的转换又是怎样呢?
这里首先记住十进制转换其余进制的通用方法:
“除基数B取余,逆序排列”方法能够将十进制数转换为任意进制数。
那么这个基数B是啥呢?好比十进制转换成二进制,那么这个基数B就是2,知道了吧!
那么其余进制转换成十进制怎么整嘞?记住这个公式:
举个例子,好比以前1011这个二进制转换成十进制就能够这样:
了解了进制转换,尤为是十进制和二进制之间的转换以后咱们就能够开始学习java中的位运算了,由于位运算实际上都是对二进制进行操做的,接下来我将逐步分析java中常见的位运算。
举个栗子,5 << 2 将5左移2 结果为20 为啥?注意是对二进制进行的操做,来看:
首先会将5转为二进制表示形式(java中,整数默认就是int类型,也就是32位):
0000 0000 0000 0000 0000 0000 0000 0000
这就是32位,可是每位上都是0,这是一个标准,用于后面的比较,好比5的二进制是
0000 0000 0000 0000 0000 0000 0000 0101
而后把它与标准的进行对比,也就是这样:
换算成十进制就是20了 这就是5 << 2获得结果的由来。
仍是先将5转为2进制表示形式:
0000 0000 0000 0000 0000 0000 0000 0101 而后右移2位,高位补0:
0000 0000 0000 0000 0000 0000 0000 0001
看图:
先记住这句话:正数右移,高位补0,负数右移,高位补1,负数无符号右移,高位补0 正数无符号右移 ,高位补0 正数换算成二进制后的最高位为0,负数的二进制最高位为1
接下来依然是看例子,在此以前我看过好多别人写的,发现好多都喜欢用5举例子你知道为啥吗😂
5换算成二进制是: 0000 0000 0000 0000 0000 0000 0000 0101
5右移3位后结果为0,0的二进制为: 0000 0000 0000 0000 0000 0000 0000 0000 // (这里高位补0)
-5换算成二进制是: 1111 1111 1111 1111 1111 1111 1111 1011
-5右移3位后结果为-1,-1的二进制为: 1111 1111 1111 1111 1111 1111 1111 1111 // (高位补1)
-5无符号右移3位后的结果 536870911 换算成二进制: 0001 1111 1111 1111 1111 1111 1111 1111 // (高位补0)
这里须要注意了:以上说的都是右移的状况,若是是左移,不管是正数仍是负数,低位都是用0补
时间关系,就不赘述了。
其实核心都是二进制,因此掌握好进制转换是关键,看看位与 &是怎么计算的:
有0则0,不然为1
什么意思呢?咱们举一个例子来看看
规则就是:有1则1
看例子:
规则是:相同则0,不一样则1
看例子:
这是网站随便找的一个例子,你看看,求~5,得-6,为啥?
不知道你懂吗?有这么一个解释:
6的二进制数为: 0000 0000 0000 0000 0000 0000 0000 0110 而后6的二进制反码为: 1111 1111 1111 1111 1111 1111 1111 1001 将反码+1获得-6的补码二进制数:1111 1111 1111 1111 1111 1111 1111 1010
因此这里就牵涉到原码,反码和补码了,另外还有个重点的点就是:
负数在计算机中是以补码的形式存在的
好了,咱们赶忙来看看什么是原码,反码和补码吧!
这是很是重要的概念,须要熟练掌握,要记得。开始以前,先上一个重要的结论:
数据在计算机中的存储是二进制的形式,二进制简单来讲就是0和1组合的,不管原码,反码仍是补码,都是二进制的形式
其次咱们要注意的点就是正数和负数的原码,反码和补码,是有区别的。
什么是原码嘞?
对于正数来讲,咱们把它的绝对值转换成的二进制数叫作正数的原码,对于负数来讲咱们把它的绝对值转换成的二进制数,而后最高位补1,称为原码。看看,仍是有区别的。
好比 :
00000000 00000000 00000000 00000101 是 5的 原码。
10000000 00000000 00000000 00000101 是 -5的 原码。
这里有个点就是最高位是0表明正数,是1表明负数。
接下来就是在计算机中的表示:
对于正数:原码,反码和补码都是同样的,因此在计算机中怎么说都同样,反正就是自己转换成二进制的结果,能够说原码,也能够说补码,由于都是同样的
对于负数:原码,反码和补码是不同的,在计算机中负数是以补码的形式存在的
因此说,重点聚焦在负数上,看它的反码和补码是怎么表示的
那反码是啥嘞?
负数的反码为对该数的原码除符号位外各位取反[每一位取反(除符号位)]。
这里有个符号位,啥?还记得刚刚说的吗?
最高位是0表明正数,是1表明负数。
也就是最左边的那一位。
取反操做指:原为1,得0;原为0,得1。(1变0; 0变1)
好比:
正数00000000 00000000 00000000 00000101 的反码仍是
00000000 00000000 00000000 00000101
负数10000000 00000000 00000000 00000101 的反码则是
11111111 11111111 11111111 11111010
另外啊反码是相互的,所以也可称:
10000000 00000000 00000000 00000101 和 11111111 11111111 11111111 11111010互为反码。
不过这里有个问题,那就是+0和-0,什么意思呢?
原码和反码在表示数的时候的有点尴尬啊,好比表示零的时候,一样都是0,可是原码就有两种表示法:
[-0]原=10000000
[+0]原=00000000
复制代码
反码也有两种表示法:
[+0]反=00000000
[- 0]反=11111111
复制代码
这就有点难受啊,不都是0吗,因而乎,就出了补码
那啥又是补码嘞?
负数的补码为对该数的原码除符号位外各位取反,而后在最后一位加1
好比:10000000 00000000 00000000 00000101 的反码是:11111111 11111111 11111111 11111010
那么,补码为:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
这里有两点须要注意:
一、从补码求原码的方法跟原码求补码是同样的 ,也能够经过彻底逆运算来作,先减一,再取反。
二、补码却规定0没有正负之分
第二个啥意思呢,也就是说对于0的表示,补码只有一种[-0]补=00000000。感受这样就正常多了。
原码表示法规定:用符号位(最左边)和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。
反码表示法规定:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
补码表示法规定:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,而后在最后一位加1.
正零和负零的补码相同,[+0]补=[-0]补=0000 0000B
其实你看,这些基础知识仔细研究起来,仍是有必定难度的,以为乱巴巴的,怪不得上大学的时候听不懂呢😂,并且这三个知识点貌似常常一块儿运用,因此对于这三点基础,仍是有必要花时间琢磨一番的。
好啦,就到这了,欢迎你们一块儿讨论!
你们好,我是ithuangqing,一路走来积累了很多的学习经验和方法,并且收集了大量的精品学习资源,如今维护了一个公众号【编码以外】,寓意就是在编码以外也要不停的学习,主要分享java技术相关的原创文章,如今主要在写数据结构与算法,计算机基础,线程和并发以及虚拟机这块的原创,另外针对小白还在连载一套《小白的java自学课》,力求通俗易懂,由浅入深。同时我也是个工具控,常常分享一些高效率的黑科技工具及网站。
对了,公众号还分享了不少个人学习心得,能够一块儿探讨探讨!
关注公众号,后台回复“庆哥”,2019最新java自学资源立马送上!更多原创精彩尽在【编码以外】
感谢各位大大的阅读🥰