進制轉(zhuǎn)換以及原跳仿、反菲语、補碼
——TechZone(Harris)
可能有的小伙伴不理解了:為啥這節(jié)講這些呢山上,不應(yīng)該先把語法什么的學(xué)習(xí)一下嗎胶哲?
在之前的文章里面講過潭辈,C語言的學(xué)習(xí)是需要了解一點計算機工作原理的把敢。可能在初學(xué)時期用不到婶恼,但是如果真的要深入研究的話勾邦,是絕對避免不了的。況且這節(jié)的內(nèi)容其實比較簡單荔泳,我們不如先把它了解了玛歌,方便日后我們的進階學(xué)習(xí)支子。
學(xué)習(xí)編程叹侄,尤其是底層編程圈膏,進制轉(zhuǎn)換是一個避免不了的話題稽坤。其實我們仔細(xì)去觀察尿褪,發(fā)現(xiàn)其實是有不少規(guī)律可循的杖玲。
進制轉(zhuǎn)換
-
二進制 -> 十進制
這個方法就四個字:
按權(quán)相加
我們先來了解下位權(quán)的概念摆马,舉個栗子你就明白啦:
二進制數(shù) 00101011 對應(yīng)位權(quán) 76543210 于是就有了方法:
十進制 = 依次將每個二進制位的值乘以2的位權(quán)次方再相加
=
+
+
+
+
+
+
+
= 42
另外說明一下:按權(quán)相加適用于任何進制的數(shù)到十進制的數(shù)的轉(zhuǎn)換喲述呐!
-
二進制(補碼) -> 十進制
如果符號位為0,那就和上面一種情況一樣进肯。
如果符號位為1,則此時符號位的位權(quán)不變棉磨,但該位的權(quán)值應(yīng)該乘以-1江掩,如:
=
= -68
大家可能看懵了,啥是符號位含蓉?補碼又是啥频敛?別急,后面且聽我娓娓道來馅扣。
-
十進制 -> 二進制
這好像大家高中的時候?qū)W過吧斟赚,這里我總結(jié)下:
將待轉(zhuǎn)換的十進制數(shù)不斷地除以2,直到商為零差油,然后將每次除得的余數(shù)倒序拼湊即可拗军。
-
二進制 -> 八進制
這個很簡單,只需要把數(shù)字從0位權(quán)開始三個一組分開发侵,然后分別轉(zhuǎn)化成八進制數(shù)再拼接起來即可钱骂。這里提供個表格,方便不想轉(zhuǎn)換的同學(xué)查表。
二進制 八進制 000 0 001 1 010 2 011 3 100 4 101 5 110 6 111 7
-
二進制 <-> 十六進制
這個就更簡單了省核,只需要記住如下的表格旧噪,然后將二進制數(shù)從0位權(quán)開始四個一組分開陪毡,分別對應(yīng)后再重新拼湊即可。
二進制 十六進制 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 8 1001 9 1010 A 1011 B 1100 C 1101 D 1110 E 1111 F
原碼
在了解這些碼之前呢,我們先來了解一下基本知識。
首先,我們要知道陨倡,計算機中杂曲,存放一個數(shù)據(jù)最小的單位是bit(位,也稱比特)煤裙,而在TCP/IP協(xié)議中题翰,規(guī)定1Byte = 8bit
血公,Byte(字節(jié))是最小的容量單位荚虚。因此渴析,一個字節(jié)里面就有8個位母债。那么如果使用一個字節(jié)來表示數(shù)字的話昧辽,就是個數(shù)。那么為了表示數(shù)字的符號,我們又規(guī)定王暗,一個字節(jié)中的最高位(也就是最左邊的那一位)是符號位绷雏,符號位為0表示的是非負(fù)數(shù)(記住期吓,是正數(shù)和0),1則表示的是負(fù)數(shù)。
原碼奶躯,實際上就是將十進制數(shù)轉(zhuǎn)化成二進制的形式喂江,然后把符號位加上即可蹬铺。比如說5的原碼,先轉(zhuǎn)化為二進制与帆,即101
,再填充至7位玻蝌,即000 0101
舵盈,然后因為是非負(fù)數(shù)锨能,符號位為0
,那么5的原碼就是0000 0101
秃殉。
明白了吧绢要,是不是覺得特別簡單呢哀九?那么-5的原碼又是啥呢?
聰明的你一定想到了,就直接把符號位變?yōu)?code>1就行啦,即1000 0101
跃赚。
簡直完美啊,如此簡潔地表達了數(shù)字在存儲器中的表示方式报咳。直觀形象又好記侠讯!
But!現(xiàn)在該說但是了暑刃。請問5和-5相加等于多少呢继低?
0啊稍走!當(dāng)然是0袁翁!這難道還要思考嗎柴底??
是的粱胜,沒錯柄驻,但是你用兩個數(shù)的原碼加起來看看等于幾?
咦焙压?咋就不等于0了呢……
沒錯鸿脓,問題就在這。如果用這種所謂的直觀的形式去表達涯曲,既有悖于我們的常識野哭,又不方便計算機的電路設(shè)計,于是我們的先人們開始了探索幻件。
反碼
我們從上面的例子了解到拨黔,負(fù)數(shù)在表達的時候,不能這么圖方便绰沥,不然可能會造成一些沖突和錯誤篱蝇。先人們就開始折騰。結(jié)果弄出來反碼這個東西徽曲。
我們說了零截,只是負(fù)數(shù)的表達除了問題,所以正數(shù)無論是原碼秃臣,反碼還是后面我們講的補碼涧衙,都是不變的。要變的只有負(fù)數(shù)奥此。
負(fù)數(shù)原碼轉(zhuǎn)反碼的方法很簡單绍撞,符號位單獨不變,只需要把其他的按位取反即可得院。什么叫按位取反呢,說成人話章贞,就是0變1祥绞,1變0。還是拿剛剛的-5作為栗子鸭限。-5的原碼為
1000 0101
那么轉(zhuǎn)化為反碼蜕径,符號位不變,其余按位取反:
1111 1010
懂了吧败京,那么這樣5和-5相加會得到什么呢兜喻?
我們發(fā)現(xiàn),得到了一個8bit能表示的最大的值赡麦。這個路子能否成功朴皆,就看臨門一腳了帕识。距離成功僅一步之遙。
補碼
這個“臨門一腳”就交給補碼啦遂铡。補碼的出現(xiàn)肮疗,相反數(shù)相加不為0的情況才被徹底解決。那么補碼又是個啥東東呢扒接?
正數(shù)的補碼還是原碼伪货,這個剛剛說過了。而負(fù)數(shù)的補碼钾怔,則是在反碼的基礎(chǔ)上加個1碱呼。可為啥是1呢宗侦?上面那個反碼的例子愚臀,我相信大家是有些想法了,如果給1111 1111
這個數(shù)加個1凝垛,那么等于多少呢懊悯?
答案是1 0000 0000
。
又的小伙伴可能會抬杠了梦皮,那還是不等于0呀炭分。我們注意觀察,這個數(shù)已經(jīng)達到9位了剑肯,最高位已經(jīng)溢出一個Byte捧毛,那么對于一個Byte所表示的數(shù)字,計算機可以將最高位直接舍棄让网,bingo呀忧!不就變成0000 0000
了嗎?
是不是很奇妙呢溃睹?不得不說而账,先人們著實厲害呀,在這里向他們致敬因篇!
另外泞辐,還要提醒一點,就是補碼的補碼就是原碼竞滓,至于為什么大家可以回去自己試試咐吼,這里就不多贅述咯('')
最后,在這篇文章結(jié)束前商佑,我還想提醒一句:正數(shù)是三碼歸一>馇选!別到時候別人給你一個正數(shù)叫你轉(zhuǎn)換,你還按位取反啥啥啥的肌幽,那樣就丟人啦晚碾!
今天的博客就到此結(jié)束啦,如果你喜歡筆者的文章牍颈,記得點個贊哦(≧?≦)?