深入理解计算机底层为什么采用补码运算【如何理解二进制计算高位溢出】
在計(jì)算機(jī)底層運(yùn)算設(shè)計(jì)的過程中,是根據(jù)現(xiàn)實(shí)生活中的數(shù)學(xué)運(yùn)算做出的映射。比如數(shù)學(xué)中的8-3=8+(-3),那么這樣一來減法運(yùn)算就變成了加法運(yùn)算(你這時(shí)可能會(huì)問,我腦子直接計(jì)算8-3=5了,何必再轉(zhuǎn)換位成加法運(yùn)算多此一舉,只能說你日常形成習(xí)慣了吧!因?yàn)閷?-3做分解就只有8和-3這兩部分,所以在數(shù)學(xué)中就是8和-3做相加),因此計(jì)算機(jī)底層設(shè)計(jì)模擬數(shù)學(xué)就需要負(fù)數(shù),這個(gè)負(fù)數(shù)就可以使用反碼進(jìn)行充當(dāng)–》本質(zhì)上是為了將減法運(yùn)算轉(zhuǎn)換為加法運(yùn)算。補(bǔ)碼是為了解決數(shù)字“0”在計(jì)算機(jī)中非唯一編碼的問題。為什么會(huì)這樣,往下看!
Computer_Base__Binary_List:
- 1.為什么計(jì)算機(jī)內(nèi)部只有加法器?
- 2.計(jì)算機(jī)為什么會(huì)需要原碼、反碼、補(bǔ)碼?
- 3.如何理解二進(jìn)制計(jì)算高位溢出?
1.為什么計(jì)算機(jī)內(nèi)部只有加法器?
我們都知道計(jì)算機(jī)芯片內(nèi)部有個(gè)核心部件-晶體管,但你知道它的作用嗎?作用很多,此處列舉一個(gè)與本文相關(guān)的。
通過三極管的拼接可以完成邏輯的運(yùn)算,制造出了與非門。(至于為什么本文不做探討)
(1)與門:兩個(gè)輸入端和一個(gè)輸出端,當(dāng)輸入端都為高電平(1)時(shí),才能輸出高電平(“&”)
(2)非門:一個(gè)輸入端和一個(gè)輸出端,當(dāng)輸入端為高電平(1)時(shí),輸出端為低電平,“非”也就是相反的意思。(“!”)
(3)或門:兩個(gè)輸入端和一個(gè)輸出端,當(dāng)某一個(gè)輸入端為高電平(1),那么輸出端就為高電平。(“|”)
最終通過與門、非門、或門的有機(jī)結(jié)合創(chuàng)造出了加法器。有了加法器還要解決減法器的問題,這個(gè)減法器的設(shè)計(jì)更為困難(比如加法器可以使用“與”來完成進(jìn)位),所以為了硬件電路變得簡單,我們可以通過加法器實(shí)現(xiàn)減法器的功能。這就涉及到了補(bǔ)碼。
2.計(jì)算機(jī)為什么會(huì)需要原碼、反碼、補(bǔ)碼?
二進(jìn)制第一位一般會(huì)表示成符號(hào)位,0正,1負(fù)二進(jìn)制第一位一般會(huì)表示成符號(hào)位,0正,1負(fù)二進(jìn)制第一位一般會(huì)表示成符號(hào)位,0正,1負(fù)
🌹(1)原碼
將一個(gè)整數(shù)轉(zhuǎn)換為二進(jìn)制形式就是其原碼。
比如byte a = 3;那么a的原碼就是0000 0011
比如short a = 3;那么a的原碼就是0000 0000 0000 0011
比如int a = 3; …
如何理解不同類型等到二進(jìn)制位數(shù)呢?
一個(gè)byte占1個(gè)字節(jié)(一個(gè)字節(jié)也就是8位二進(jìn)制數(shù))
一個(gè)short int 占用2個(gè)字節(jié)(也就是16位二進(jìn)制數(shù))
一個(gè)int 占用4個(gè)字節(jié)(也就是32位二進(jìn)制數(shù))
…
總結(jié):簡單了說原碼就是一個(gè)整數(shù)的二進(jìn)制形式。
🌹(2)反碼
對于正數(shù),它的反碼和原碼相同。
比如short a = 3, 它的反碼=原碼=0000 0000 0000 0011
對于負(fù)數(shù),它的反碼是將原碼中除了符號(hào)位以外的所有位進(jìn)行取反獲得。(也就是0變1,1變0)
比如short a = -3,那么它的原碼是1000 0000 0000 0011,它對應(yīng)的反碼是1111 1111 1111 1100.
有了原碼為什么還會(huì)需要反碼呢?
這就類似于數(shù)學(xué)中的4-2=4+(-2),反碼相當(dāng)于負(fù)數(shù),可以將減法變成加法。
🌹(2)補(bǔ)碼
有了反碼為什么還需要補(bǔ)碼呢?
這其實(shí)是因?yàn)?這個(gè)模糊的概念造成的。8位二進(jìn)制反碼表示的正數(shù)范圍為(0000 0000 ~ 0111 1111,高位為符號(hào)位),也就是+0~127;8位二進(jìn)制反碼表示的負(fù)數(shù)范圍為(1000 0000 ~ 1111 1111),也就是-127 ~ -0。
其中涉及到了兩個(gè)特殊的編碼+0和-0。由于計(jì)算機(jī)中的編碼是唯一的,所以需要解決這個(gè)問題。
官方給出的解決方案是正數(shù)范圍保持不變,負(fù)數(shù)范圍整體向后移動(dòng)一位,也就是反碼+1.(所以負(fù)數(shù)范圍就變成了128~-1)
有位大佬說的很貼切,這種操作好像是在反碼上打了“補(bǔ)丁”,修正了一下,所以稱之為補(bǔ)碼。
這樣一來補(bǔ)碼就很清晰了
正數(shù)的補(bǔ)碼和原碼一致
負(fù)數(shù)的補(bǔ)碼=反碼+1
總結(jié):補(bǔ)碼是為了解決數(shù)字“0”在計(jì)算機(jī)中非唯一編碼的問題。
3.如何理解二進(jìn)制計(jì)算高位溢出?
這就是涉及到了模運(yùn)算。
很多技術(shù)朋友都是列舉的是時(shí)鐘的例子,可能這個(gè)比較容易理解吧!
假設(shè)當(dāng)前時(shí)鐘指向4點(diǎn),怎么將它指向2點(diǎn)呢?
1.直接向后撥動(dòng)兩位到2點(diǎn)【4-2=2】
2.向前撥動(dòng)十位就到2點(diǎn)了【(4+10)mod 12】
從以上我們可以看出-2和10在數(shù)學(xué)上互為補(bǔ)數(shù)
所以可以總結(jié)出
A-B=(A+B補(bǔ))mod N(N表示極限值)
看下面的二進(jìn)制補(bǔ)碼計(jì)算溢出的情況
4-3=? 【假設(shè)這兩個(gè)都是byte類型,也就是一個(gè)字節(jié),8位二進(jìn)制數(shù)】
4的補(bǔ)碼為0000 0100
-3的補(bǔ)碼為1111 1101
相加之后為1 0000 0001,可以看出已經(jīng)超出了byte的-128~127的范圍,由于存儲(chǔ)限制,進(jìn)位1會(huì)被丟棄。
最終的結(jié)果0000 0001,對應(yīng)的十進(jìn)制也就是1,剛好滿足結(jié)果,你可能會(huì)有疑問為什么這么巧呢?
原因如下:
這就類似于上面涉及到的模運(yùn)算,1 0000 0000剛好是該byte的極限值,由于計(jì)算機(jī)存儲(chǔ)的限制,所以會(huì)將高位1進(jìn)行舍棄。其值就是0.
對于-3我們可以理解為0-3,0-3對應(yīng)的二進(jìn)制也就是1 0000 0000 - 0000 0011 = 1111 1101 = -3的反碼 + 1 = -3的補(bǔ)碼。
另外也可也可以利用上面的mod進(jìn)行理解這個(gè)溢出。
總結(jié)
以上是生活随笔為你收集整理的深入理解计算机底层为什么采用补码运算【如何理解二进制计算高位溢出】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JVM调优工具篇】使用JProfile
- 下一篇: 实验4 贪心法(作业调度问题)