为了更好的读源码,你必须搞定这些java基础知识!(位运算,进制转换和原码,反码和补码)

不知道上一篇文章看的怎么样了:惧怕面试被问HashMap?这一篇就搞定了!
在这篇文章中,我比较详细的分析了为何HashMap的初始化容量是16以及为何容量的大小要是2的整数次幂!java

不知道你看懂了没,若是你看的懵懵懂懂的话,我猜你对如下基础知识必定不那么熟悉:web

  1. java中的位运算
  2. 进制之间的转换
  3. 原码,反码和补码

怎么样,对这些基础知识掌握的如何,这些能够说都是大学时候学的计算机基础了,不过,我知道你当时确定没学会,即便学会了也忘得差很少了。面试

其实吧,这些基础知识真的超级重要,你看,如今阅读源码的时候由于这些基础知识不过关而遇到坎了吧。算法

别担忧,今天我们一块儿越过这道坎!数据结构

先从进制转换开始

对于进制转换这个啊,说来惭愧,我以前学过不止一次,曾经有一次还花了很长时间,作笔记,画图,弄了满满的一张A4纸,当时以为对进制转换这块彻底OK了,之后不再怕进制转换了。并发

但是嘞后来读源码的时候遇到进制转换的时候仍是以为不知所措,发现以前学的都忘得差很少了,唉。app

因此啊,对于学习,咱们可不能一味的向前学习新知识,对于以前的知识也要常常回顾,温故而知新,能够为师矣嘛工具

好啦,我们此次再来一块儿学习下进制转换吧!学习

对于进制转换啊,其实咱们的重点主要放在与十进制之间的各类转换便可,由于这才是咱们日常使用频率比较高的,因此要优先熟练的掌握这些。网站

啥是二进制

十进制咱们再熟悉不过了,那啥是二进制嘞,简单来讲,二进制就是用0和1来表示的数值,在十进制中逢十进一,借一当十,而二进制呢?那就是逢二进一,借一当二,这个好懂,可是这里我要说些概念。

什么嘞?后面咱们要说到原码,反码和补码,这里先说下,它们都是二进制数,也就是都是由0和1表示的,单是可能具体的数值不同。

咱们要知道,对于计算机而言,它只认识0和1,因此对于数据在计算机中的存储都是以二进制的形式来存储的,好了,先有这个概念。

十进制与二进制之间的一个规律

先来看一个图:

在这里插入图片描述
在这里插入图片描述

不知道你看出来什么没,主要看标红的,前面说过了,二进制就是逢二进一,那么上图中标红的二进制是否是都是产生进位的数值,啥意思嘞,好比二进制11,并无产生进位,若是要产生进位,那就要再加一,而后就会产生进位得100,你看是否是?

再看进位产生的二进制对应的十进制是否是这些数值:

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,余数逆序排列,看个例子吧:

在这里插入图片描述
在这里插入图片描述

也就是说十进制转换成二进制的话,那就用十进制的数除以2,而后取余数以后将余数逆序排列就是对应的二进制数了,怎么样是否是更简单,咱们接着往下看

十进制与其余进制之间的转换

咱们以前就说过,对于进制转换咱们重点关注的就是与十进制之间的转换,咱们上面介绍了二进制和十进制之间的互相转换,那么还有八进制和十六进制,它们与十进制之间的转换又是怎样呢?

这里首先记住十进制转换其余进制的通用方法:

“除基数B取余,逆序排列”方法能够将十进制数转换为任意进制数。

那么这个基数B是啥呢?好比十进制转换成二进制,那么这个基数B就是2,知道了吧!

那么其余进制转换成十进制怎么整嘞?记住这个公式:

在这里插入图片描述
在这里插入图片描述

这个公式能够归纳为:“按权展开”—其余进制转换为十进制(B表示各进制的基数,n表示位数)

举个例子,好比以前1011这个二进制转换成十进制就能够这样:

在这里插入图片描述
在这里插入图片描述

就是这样的啦,至于其余的什么八进制和十六进制之间的互相转换什么的,不怎么经常使用,感兴趣的自行了解,对了,我日常都是直接搜索在线进制转换的😂

进攻位运算

了解了进制转换,尤为是十进制和二进制之间的转换以后咱们就能够开始学习java中的位运算了,由于位运算实际上都是对二进制进行操做的,接下来我将逐步分析java中常见的位运算。

左移 <<

举个栗子,5 << 2 将5左移2 结果为20 为啥?注意是对二进制进行的操做,来看:

首先会将5转为二进制表示形式(java中,整数默认就是int类型,也就是32位):

在这里插入图片描述
在这里插入图片描述

怎么去理解,首先在Java中,整数默认就是int类型,也就是占4个字节32位,你就能够想成这样

0000 0000 0000 0000 0000 0000 0000 0000

这就是32位,可是每位上都是0,这是一个标准,用于后面的比较,好比5的二进制是

0000 0000 0000 0000 0000 0000 0000 0101

而后把它与标准的进行对比,也就是这样:

在这里插入图片描述
在这里插入图片描述

这时候的区别就在后四位,而后将5左移(<<)2,也就是5的二进制以标准为参考总体左移2位,也就是这样:

在这里插入图片描述
在这里插入图片描述

这样一来,就产生了错位,看图:
在这里插入图片描述
在这里插入图片描述

不过这时候看着老是有点别扭,应该都是四位四位的在一块吧,因此从低位开始,四位一组,就成了这样
0000 0000 0000 0000 0000 0000 0001 0100

换算成十进制就是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

什么意思呢?咱们举一个例子来看看

在这里插入图片描述
在这里插入图片描述

咱们猜这个结果是什么,答案是

在这里插入图片描述
在这里插入图片描述

注意这里可不是6除以3,它是这样计算的,首先6和3都要转成二进制,6的二进制是110,3的二进制是11也就是011,那么这样运算

在这里插入图片描述
在这里插入图片描述

我相信看图就能明白的,而二进制的010就是2啦,这就是位与的操做,对于或和亦或其实一样道理,咱们继续来看:

位或 |

规则就是:有1则1

看例子:

在这里插入图片描述
在这里插入图片描述

位异或 ^

规则是:相同则0,不一样则1

看例子:

在这里插入图片描述
在这里插入图片描述

有点难懂的位非 ~

这是网站随便找的一个例子,你看看,求~5,得-6,为啥?

在这里插入图片描述
在这里插入图片描述

它这里的规则是:操做数的第n位为1,那么结果的第n位为0,反之。

不知道你懂吗?有这么一个解释:

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自学资源立马送上!更多原创精彩尽在【编码以外】

在这里插入图片描述
在这里插入图片描述

感谢各位大大的阅读🥰

相关文章
相关标签/搜索