您好,歡迎進(jìn)入深圳市穎特新科技有限公司官方網(wǎng)站!
首先,閱讀這篇文章的你,肯定是一個(gè)在網(wǎng)上已經(jīng)糾結(jié)了很久的讀者,因?yàn)槟悴殚喠怂心隳懿榈降馁Y料,然后他們都會(huì)很耐心的告訴你,補(bǔ)碼:就是按位取反,然后加一。準(zhǔn)確無(wú)誤,毫無(wú)破綻。但是,你搜遍了所有俯拾即是而且準(zhǔn)確無(wú)誤的答案,卻仍然選擇來(lái)看這篇毫不起眼的文章,原因只有一個(gè),只因?yàn)槟氵沒(méi)有得到你想要的東西。
因?yàn)槟阆胍,不?+1=2,而是,1+1為什么等于2。當(dāng)然,我們不討論1+1的問(wèn)題。我們討論的,是補(bǔ)碼。
你已經(jīng)困惑了很久,你明明知道補(bǔ)碼就是按位取反,然后加一,但是你想知道的,不是它怎么求滴,而是,它怎來(lái)滴。當(dāng)然,對(duì)于閱讀這篇文章的你,既然想要知道這個(gè)答案,一定是有一定編程基礎(chǔ)的讀者,肯定知道補(bǔ)碼與有符號(hào)數(shù)與無(wú)符號(hào)數(shù)的關(guān)系(有符號(hào)數(shù)指帶有正負(fù)號(hào)的數(shù),無(wú)符號(hào)可以理解為只大于0的數(shù)),你所查閱的所有資料首先都會(huì)用一個(gè)8位的二進(jìn)制數(shù)給你舉例,ok,我們也用一個(gè)8位的二進(jìn)制數(shù)。
8位二進(jìn)制數(shù),最小00000000,最大數(shù)11111111,換算十進(jìn)制為0~255,當(dāng)然,所有的參考資料都會(huì)這樣講,而且這也不是你想要的,但我們必須說(shuō)下去。1~255,一共255的字符,再加上最前面的0,一共256個(gè)字符,F(xiàn)在,我們要用一個(gè)8位二進(jìn)制數(shù)字來(lái)表示一個(gè)負(fù)數(shù),可是二進(jìn)制里沒(méi)有負(fù)號(hào),誰(shuí)都知道二進(jìn)制里只有0,1,再無(wú)其他符號(hào)。那么所以我們必須用一種方式來(lái)代替正負(fù),也就是我們規(guī)定,當(dāng)然是人規(guī)定的,而不是電腦,我們規(guī)定這個(gè)8位的二進(jìn)制數(shù)的最前面一位數(shù)來(lái)表示這個(gè)數(shù)的正負(fù),0代表是正,1代表是負(fù)。那么當(dāng)?shù)谝晃皇?時(shí),我們一共可以表示00000000~01111111這么多正數(shù),因?yàn)榈谝晃槐仨毷?來(lái)代表正數(shù);當(dāng)?shù)谝晃皇?時(shí),我們一共可以表示10000000~11111111這么多負(fù)數(shù),然后,我們用00000000~01111111來(lái)代表0~127,那豈不是10000000~11111111代表 -0 ~ -127??可是網(wǎng)上都說(shuō)不能有 負(fù)0,可是我覺(jué)的沒(méi)什么不妥啊,負(fù)0不還是0 嗎?10-0=10,不就是相當(dāng)于10+(-0)=10嗎,現(xiàn)在我們不討論正負(fù)0的問(wèn)題,我們來(lái)討論一個(gè)小學(xué)生的問(wèn)題。
我們現(xiàn)在要把00000000~11111111分成兩組數(shù),一組是正數(shù),另一組是負(fù)數(shù),正數(shù)是0,1,2,3,4,5,6,7,8,… 負(fù)數(shù)是 -1,-2,-3,-4,-5,-6,-7,-8,… 那么這里就有一個(gè)小學(xué)問(wèn)題,那就是1+(-1)肯定要等于0,2+(-2)=0,他們是相反數(shù),相加等于0,小學(xué)生都會(huì)。后面都是一樣,那么現(xiàn)在我們使用上面的編碼的方式進(jìn)行一個(gè)計(jì)算,現(xiàn)在上面的編碼中 1 對(duì)應(yīng)的二進(jìn)制是00000001,-1對(duì)應(yīng)的二進(jìn)制是10000001,然后你把這倆二進(jìn)制數(shù)加起來(lái),看看等于幾,對(duì),答案是10000010,不是00000000,也不是10000000, 10000010在上面的編碼中代表 -2,00000000和10000000都在上面代表0,可是結(jié)果并不是他們。而00000001與10000001分別對(duì)應(yīng)著1和-1,加起來(lái)理論的結(jié)果應(yīng)該是0才對(duì),也就是說(shuō)上面的編碼是錯(cuò)誤的。
或許接下來(lái)很多資料又討論了反碼,但是我們不,我們來(lái)求一個(gè)一元一次函數(shù),一個(gè)小學(xué)的函數(shù),1+x=0,求x=?,答:-1。沒(méi)錯(cuò),而且準(zhǔn)確無(wú)誤。那么現(xiàn)在問(wèn)題來(lái)了,前面的正數(shù)編碼應(yīng)該是沒(méi)有錯(cuò)的,00000000代表0, 00000001代表1,這些都符合我們的習(xí)慣,那么出錯(cuò)的是在后面的負(fù)數(shù)編碼上,我們到底該如何編碼對(duì)應(yīng)負(fù)數(shù)編碼它才能正確呢,因?yàn)槲覀冎?+(-1)必須等于0,也就是他們對(duì)應(yīng)的二進(jìn)制相加也必須等于0,1對(duì)應(yīng)00000001,那么00000001+x=00000000,里面的x就應(yīng)該代替 -1的二進(jìn)制編碼才對(duì),這樣,我們得到 x=11111111,大家看一下這和按位取反,然后加一的結(jié)果一樣嗎。
所以我們的結(jié)論是,一個(gè)正數(shù)對(duì)應(yīng)的負(fù)數(shù)(也就是倆相反數(shù)),這兩個(gè)數(shù)的二進(jìn)制編碼加起來(lái)必須等于0才對(duì),所以我們只要知道其中一個(gè)數(shù)的編碼x,然后用0-x就是他對(duì)應(yīng)的數(shù)的編碼,這樣的話,從0~127,我們用(0 - 其中一個(gè)二進(jìn)制數(shù)的編碼)=(另一個(gè)二進(jìn)制數(shù)的編碼),例如 2 的二進(jìn)制編碼是00000010,那么-2 的二進(jìn)制編碼就是0 - 00000010=11111110,因?yàn)樗蛻?yīng)該這樣,因?yàn)樗褪且粋(gè)小學(xué)問(wèn)題,他倆加起來(lái)就應(yīng)該等于0。那么1000000對(duì)應(yīng)的編碼是多少呢,當(dāng)然也必須滿足加起來(lái)等于0才行,那么10000000+x=0,求解x,答x=10000000,還是它本身,也就是在00000000~11111111這個(gè)范圍里所有的二進(jìn)制數(shù)都無(wú)法滿足它,也就是沒(méi)有一個(gè)數(shù)加上它等于0,但是兩個(gè)數(shù)要有對(duì)應(yīng)的編碼,就必須加起來(lái)等于0才行,其實(shí)不止它沒(méi)有,0也沒(méi)有,0+x=0,那么x=0,也是它本身,既然這樣了,那么也沒(méi)有辦法了,無(wú)可奈何只能做單身漢了,然后我們規(guī)定,既然10000000第一位是1,代表負(fù)數(shù),那么我們規(guī)定它是一個(gè)負(fù)數(shù),那么10000000就代替了-128,而且,它只自己一個(gè)人,也就是只有-128,沒(méi)有正數(shù)128。
然后,他們每個(gè)數(shù)都有了自己對(duì)應(yīng)的編碼,而且準(zhǔn)確無(wú)誤。1~127對(duì)應(yīng)-1~ -127,再加上兩個(gè)單身漢0和-128。然后呢,不知道誰(shuí)起的名字,就把這種編碼叫做了補(bǔ)碼,如果你樂(lè)意,你也可以給它起個(gè)名字。但是呢,還有一個(gè)問(wèn)題,為什么補(bǔ)碼的求法是按位取反再加一呢,其實(shí)當(dāng)你不明白為什么各大書籍都要用按位取反來(lái)計(jì)算補(bǔ)碼的時(shí)候,我們完全可以直接用0減去它就得到他相反數(shù)的二進(jìn)制編碼了,譬如隨便一個(gè)十六進(jìn)制數(shù) 6C ,那么我們可以直接0-6C就得到他的相反數(shù)的補(bǔ)碼了,結(jié)果為十六進(jìn)制的94,跟按位取反再加一的效果一樣。
現(xiàn)在我們知道補(bǔ)碼是怎么來(lái)的了,也就是為了保證兩個(gè)相反數(shù)對(duì)應(yīng)二進(jìn)制的和必須是0,然后又不知道誰(shuí)給它起了補(bǔ)碼這個(gè)名字。補(bǔ)碼補(bǔ)碼,有沒(méi)有感覺(jué)兩個(gè)相反數(shù)是互補(bǔ)的呢,也就是任意兩個(gè)相反數(shù)加起來(lái)一定等0,其中一個(gè)數(shù)變大,另一個(gè)就一定會(huì)變小互補(bǔ)保證結(jié)果為0。但是你肯定還在糾結(jié),為啥要按位取反,為啥還要加一呢。其實(shí),這涉及到一個(gè)二進(jìn)制減法的問(wèn)題,你既然知道補(bǔ)碼這個(gè)概念,就一定會(huì)知道有進(jìn)位丟失這么個(gè)東西。現(xiàn)在我們知道了補(bǔ)碼是怎么來(lái)的,也就是(00000000 - 其中一個(gè)正數(shù)的補(bǔ)碼)=(這個(gè)數(shù)相反數(shù)的補(bǔ)碼),那么我們知道了1的二進(jìn)制是00000001,那么我們來(lái)求-1的補(bǔ)碼,也就是應(yīng)該00000000 - 00000001=?,我們?cè)撛趺从?jì)算這個(gè)二進(jìn)制減法呢,而且還是一個(gè)小數(shù)減去大數(shù),連借位都沒(méi)地方借,前面我們提到進(jìn)位丟失這個(gè)東西,那么我們來(lái)計(jì)算一個(gè)算式,11111111+00000001=?知道進(jìn)位丟失的你,肯定知道加起來(lái)后等于00000000,雖然結(jié)果應(yīng)該是100000000(后面是8個(gè)0),但是只能有8位,所以最高位的1丟失了,那么現(xiàn)在好了,也就是說(shuō),我們可以把00000000看做(11111111+00000001)因?yàn)樗麄z是相等的,我們已經(jīng)計(jì)算過(guò)的了,那么我們現(xiàn)在就可以把前面講的公式中的00000000換成(11111111+00000001),也就是我們要計(jì)算-1的補(bǔ)碼,我們就0-1的編碼,也就是00000000-00000001,也就是(11111111+00000001)-00000001=(-1的補(bǔ)碼),這個(gè)算式我覺(jué)的你應(yīng)該會(huì)計(jì)算了,大數(shù)減小數(shù),到現(xiàn)在,或許你現(xiàn)在已經(jīng)發(fā)現(xiàn)什么了,是的,你發(fā)現(xiàn)了之前一直迷惑你的一個(gè)東西,“按位取反再加一”,但是可能還有一點(diǎn)迷惑,我們繼續(xù),因?yàn)槲覀兠看味际怯靡粋(gè)0減去一個(gè)數(shù)的補(bǔ)碼來(lái)得到另一個(gè)數(shù)的補(bǔ)碼,也就是里面的(11111111+00000001)是不變的,因?yàn)樗褪?,那么我們現(xiàn)在要求一個(gè)數(shù)的補(bǔ)碼,就是(11111111+00000001)- 一個(gè)數(shù)的補(bǔ)碼=它相反數(shù)的補(bǔ)碼,咱們把括號(hào)去掉,也就是11111111 - 一個(gè)數(shù)的補(bǔ)碼+00000001=它相反數(shù)的補(bǔ)碼,這是加法交換法則,只是把位置交換一下,小學(xué)生都會(huì)的,然后呢再加個(gè)括號(hào)方便我們理解,也就是(1111111 - 一個(gè)數(shù)的補(bǔ)碼)+00000001=它相反數(shù)的補(bǔ)碼。好了,問(wèn)題來(lái)了,(11111111 - 一個(gè)數(shù)的補(bǔ)碼)的結(jié)果是什么,這個(gè)你心里應(yīng)該是清楚的,你也可以算一下,它正好的等于它的反碼,也就是按位取反的一個(gè)數(shù),其實(shí)也好理解,你減幾個(gè)數(shù)就看見(jiàn)規(guī)律了,描述好麻煩,現(xiàn)在好了,也就是(11111111 - 一個(gè)數(shù)的補(bǔ)碼)=這個(gè)數(shù)的反碼,也就是(11111111 - 一個(gè)數(shù)的補(bǔ)碼)=把這個(gè)數(shù)按位取反,到現(xiàn)在,你應(yīng)該你已經(jīng)很清楚他是怎么來(lái)的了。
那么我們現(xiàn)在就可以把公式寫成這樣,(11111111 - 一個(gè)數(shù)的補(bǔ)碼)+00000001=它相反數(shù)的補(bǔ)碼,現(xiàn)在我們知道了(11111111 - 一個(gè)數(shù)的補(bǔ)碼)=把這個(gè)數(shù)按位取反,然后把公式里的(11111111 - 一個(gè)數(shù)的補(bǔ)碼)換成 “按位取反”,也就是 (按位取反)+000000001=它相反數(shù)的補(bǔ)碼,現(xiàn)在,按位取反,再加一,就終于出來(lái)了,這就是各大書籍資料所講的,補(bǔ)碼=按位取反+1..。好了,真相大白
本文章屬個(gè)人領(lǐng)悟,錯(cuò)誤必有,不吝賜教
掃碼關(guān)注我們
傳真:0755-82591176
郵箱:vicky@yingtexin.net
地址:深圳市龍華區(qū)民治街道民治大道973萬(wàn)眾潤(rùn)豐創(chuàng)業(yè)園A棟2樓A08