不知道上一篇文章看的怎麼樣了:懼怕面試被問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自學資源立馬送上!更多原創精彩盡在【編碼以外】
感謝各位大大的閱讀🥰