Java vs Python:Java 開發(fā)人員的基本 Python
866
2022-05-29
引言
點進這個文章說明你對補碼的概念也有不清楚的地方,嘻嘻,那就繼續(xù)看下去吧。
很多同學在學習二進制的時候對于補碼的理解不是很清楚,并且也不知道為什么補碼是原碼先取反然后再加一,這里就來說說我自己的理解,希望能幫到你。
二進制
我們知道計算機內部使用二進制用來表示,準確來說,計算機內部只有二進制,只有0和1,再也沒有別的數(shù)字了。0和1分別對應低電平和高電平,在磁盤中則代表S極和N極,也可以理解為正 和 反,總之0和1是不一樣的兩種狀態(tài),凡是界限分明的兩種狀態(tài)都可以用來表示0和1。
二進制數(shù)包括有符號數(shù)和無符號數(shù),這里我們討論有符號數(shù)(因為無符號數(shù)也不牽扯補碼的問題)。我們知道一個byte占用一個字節(jié),也就是8個bit,在一般的編程課程中一般都會告訴我們,1byte所能表示的數(shù)字是2^8= 256個,又因為有符號數(shù)中第一位是符號位,第一位是0則代表正數(shù),為1則代表負數(shù),全為0則代表0,所以byte所能表示的范圍是-128~127。這里比較精明的同學就會有疑問了,為什么是-128~127而不是-127~128?這將在下面講解,請繼續(xù)往下看。
補碼的由來
要了解為什么使用補碼,那么我們就要知道如果不使用補碼會遇到什么樣的問題,舉個例子大家就明白了,為了方便閱讀,我們采用8個bit進行演示,多個字節(jié)的情況類似。
比如00000000(8個0)表示0,00000001表示1,01111111表示127,那么按照常規(guī)的想法,10000001應該表示-1,10000000應該是-0(也就是0),11111111應該是-127。如下表:
在計算機中也要遵循傳統(tǒng)的數(shù)學定理,比如1-1 = 1+(-1) = 0,然而按照剛才的設想,00000001+10000001 = 10000010 = -2 ≠ 0,這違反基本的數(shù)學規(guī)律,這在一個科學的、自洽的計算機系統(tǒng)中是不允許存在的,這是存在的第一個問題;
第二個問題是,+0和-0占據(jù)了兩個位置,這樣就無法表示256個數(shù)了,只能表示255個。
那么我們需要怎么解決這個違反數(shù)學規(guī)律的問題呢?我們當然難以解決,幸好已經有偉大的計算機科學家找到了完美的解決方案,那就是補碼。補碼的規(guī)則是源碼按位取反得到反碼,然后再加1,就得到補碼。補碼與原碼互為對稱關系,即補碼是原碼的補碼,原碼也是補碼的補碼,這句話有點繞口,多讀幾遍就理解了。同理,原碼與反碼也是對稱關系,反碼是源碼的反碼,源碼是反碼的反碼。
我們再舉例子,00000001(1)取反得到11111110,再加1得到11111111,然后將00000001 + 11111111 = 00000000 = 0!!!? ?所以11111111即為-1
00000010(2)取反得到11111101,再加1得到11111110,然后將00000010 + 11111110 = 00000000 = 0!!!? ?所以11111110即為-2
01111111(127)取反得到10000000,再加1得到10000001,然后將 01111111 + 10000001 = 00000000 = 0!!!? ?所以10000001即為-127
。。。以此類推就可以得到-1~-127所對應的二進制編碼,并且滿足負數(shù)的首位(符號位)是1。
最后還剩一下一個10000000和00000000,00000000對應0,那么只剩下一個-128和10000000對應,那么為什么把10000000分配給-128而不是+128?這是因為10000000 + 00000001(1) = 10000001 = -127 ,所以10000000就等于-127 - 1 = -128。至此為止,8bit的所對應的所有的256個二進制數(shù)均與十進制數(shù)對應完畢,且完全滿足數(shù)學規(guī)律,這就是我們想要得到的。
關鍵結論
從上面的例子不難看出,滿足數(shù)學規(guī)律的情況下,
補碼所代表的就是原碼的相反數(shù),補碼所代表的就是原碼的相反數(shù),補碼所代表的就是原碼的相反數(shù)!!!
重要的事情說三遍。
可逆性驗證
進行補碼的逆運算: 11111111(-1) 減1得到? 11111110,然后按位取反得到 00000001 (1)
進行補碼運算:11111111 (-1)取反得到 00000000,再加1得到 00000001(1)
這里表明了兩種運算的方式,都可以得到-1 的相反數(shù) 1,兩種運算都可以,是等價的,這也就是取補碼的兩種方式,也就是得到相反數(shù)的方式。這里只是舉個例子,其他情況下也是符合的,請大家自行驗證。
這里只是舉8個bit位來說明問題,int表示4個字節(jié),long表示8個字節(jié)的情況大家可以自行腦補。
常見數(shù)值的換算對比表
下表列出常用的幾個數(shù)的二進制與十進制的對應關系:
結語
結尾了,還有一個疑問沒有解決,為什么是這么復雜的計算公式,先取反再加1來得到補碼?
這是因為取反之后的反碼與原碼相加會得到11111111(8個1),再加1,就會得到00000000(8個0,也就是0,限定8位,多余的一位會被計算機丟棄),兩個數(shù)相加為0,這就是相反數(shù)的特質,所以依靠這種方式能得到和為0,也就能得到相反數(shù)。這樣計算之后得到的結果有完美的的可逆性與邏輯性,也滿足了數(shù)學規(guī)律并且沒有重復分配,如此精妙絕倫,完美結合了數(shù)學特征和計算機的特質,真的佩服老一代計算機科學技術的睿智與深邃的智慧。
為什么這些計算機科學家可以這么有智慧,設計出這么完美的公式,而我等只能瞻仰學習他們的成果?我想這是厚積薄發(fā)的結果,有了深厚的知識底蘊,才能遇到事情想到最佳的解決方案,完美解決問題。而我們需要做的,就是不斷提高知識水平,夯實底蘊,在不斷的磨礪鍛煉中提高自己,同時對于細節(jié)要多練習達到熟能生巧,保持興趣與競爭力,等待厚積薄發(fā)的機會到來,一舉成名世人知。謝謝大家!
本文有點啰嗦,這也是為了照顧零基礎小白,如果能幫到你,這將是我莫大的榮幸。如果有問題可以評論加私信來和我討論,我看到的話會及時回復。本人也是初來乍到,希望能得到各位大佬的指點。謝謝!
【奔跑吧!JAVA】有獎征文火熱進行中:https://bbs.huaweicloud.com/blogs/265241
Java
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。