[干貨](méi)按位取反怎么算?~圖文詳解
時(shí)間:2019-04-26 00:00:00
來(lái)源:信盈達(dá)
作者:信盈達(dá)
學(xué)習(xí)電路,C語(yǔ)言或者其他上層語(yǔ)言都會(huì)涉及到位操作符,而其中的按位取反~最令人費(fèi)解,牽扯出一連串的東西:原碼,反碼,補(bǔ)碼等等,讓人看得云里霧里,計(jì)算不出正確的結(jié)果,真真的是讓人恨得牙癢癢。
所謂天下武功唯套路不破,今天小編就給大家解答下按位取反的計(jì)算套路,讓你以后遇到無(wú)論正數(shù)還是負(fù)數(shù)取反都不會(huì)心里犯怵,清清楚楚的計(jì)算流程,明明白白的確定答案。
1、二進(jìn)制
在了解計(jì)算規(guī)則之前,我們要先來(lái)了解下二進(jìn)制是什么,為什么要使用二進(jìn)制。
像我們?nèi)粘J褂玫臄?shù)字:1,2,3,4......等,在計(jì)算機(jī)中被稱為十進(jìn)制數(shù),逢十進(jìn)一,底數(shù)為10。
那么類似地二進(jìn)制也是一種計(jì)數(shù)的方式,使用0和1兩個(gè)數(shù)碼來(lái)表示數(shù)字,逢二進(jìn)一,它的底數(shù)為2。
電腦處理的數(shù)據(jù)不管輸入內(nèi)容是什么形式,都會(huì)轉(zhuǎn)換為二進(jìn)制數(shù)后再處理。
所以我們?cè)谶M(jìn)行位運(yùn)算的時(shí)候,也要將十進(jìn)制的數(shù)轉(zhuǎn)為二進(jìn)制的數(shù)后,再計(jì)算。
那么,十進(jìn)制數(shù)如何轉(zhuǎn)化為二進(jìn)制數(shù)呢?我們以125為例,來(lái)計(jì)算下它對(duì)應(yīng)的二進(jìn)制數(shù)。

計(jì)算過(guò)程:十進(jìn)制數(shù)除以2,商作為第二次的被除數(shù),每一次的余數(shù)保留,直到最后的商小于2為止。然后將所有的余數(shù)倒著寫,每4位為一組(二進(jìn)制在書寫時(shí),通常以4位為一組),最右邊不夠四位的補(bǔ)0。
如:111 1101 最左邊不夠4位,要補(bǔ)0湊夠4位,即0111 1101。
接下來(lái),我們?cè)賮?lái)看一下二進(jìn)制轉(zhuǎn)十進(jìn)制:
二進(jìn)制是逢二進(jìn)一的,也就是二進(jìn)制的1就是十進(jìn)制的1,當(dāng)二進(jìn)制的1加上1時(shí),它就進(jìn)位了,變成了10,也就是說(shuō):
1是一個(gè)1, .......20
10是兩個(gè)1就是一個(gè)2 .......21
100是10*10即兩個(gè)2相乘 ...... 22
1000是10*10*10即三個(gè)2相乘 ....... 23
........
所以,二進(jìn)制轉(zhuǎn)十進(jìn)制時(shí),先將二進(jìn)制的位數(shù)每四個(gè)為一組補(bǔ)齊,然后使用每位上面的數(shù)字乘以對(duì)應(yīng)的2的冪次,從左到右依次是20,21,22,23.......,然后再相加,如:
0
|
1
|
1
|
0
|
1
|
0
|
0
|
1
|
27
|
26
|
25
|
24
|
23
|
22
|
21
|
20
|
128
|
64
|
32
|
16
|
8
|
4
|
2
|
1
|
所以,二進(jìn)制的0110 1001對(duì)應(yīng)的十進(jìn)制數(shù)計(jì)算就是:
0*27+1*26+1*25+0*24+1*23+0*22+0*21+1*20
=1*64+1*32+1*8+1*1
=105
2、按位取反運(yùn)算符
位操作符有:&(按位與)、|(按位或)、^(按位異或)、~(按位取反)、<<(按位左移)、>>(按位右移),今天我們只說(shuō)~(按位取反)這個(gè)運(yùn)算符。
既然是位運(yùn)算符,那么它操作的就是二進(jìn)制數(shù)據(jù),那我們一定要先將要操作的數(shù)先變成二進(jìn)制再計(jì)算,一般我們使用的都是十進(jìn)制數(shù),十進(jìn)制數(shù)轉(zhuǎn)二進(jìn)制數(shù)的方法上面我們已經(jīng)說(shuō)過(guò)了,這里就不贅述了。
首先,讓我們來(lái)看一下取反操作的定義:~是一元運(yùn)算符,用來(lái)對(duì)一個(gè)二進(jìn)制數(shù)按位取反,即將0變1,將1變0。原理簡(jiǎn)單但是實(shí)際使用起來(lái)并不容易。
在計(jì)算機(jī)中一個(gè)整型數(shù)(int)占4字節(jié),1字節(jié)8位,所以數(shù)字5在計(jì)算機(jī)中存儲(chǔ)占32位,比如:5,我們很容易能夠得到它的二進(jìn)制是:
0000 0000 0000 0000 0000 0000 0000 0101
那么按照定義的取反就是
1111 1111 1111 1111 1111 1111 1111 1010
最高位是1表示它是個(gè)負(fù)數(shù),其他位進(jìn)行二進(jìn)制轉(zhuǎn)十進(jìn)制數(shù),這個(gè)數(shù)值非常大,但是因?yàn)槭秦?fù)數(shù),所以它代表的數(shù)很小很小。
然而,計(jì)算機(jī)的運(yùn)算結(jié)果是:
那么,這個(gè)-6是怎么算出來(lái)的呢?
這里就要涉及到正、負(fù)數(shù)在計(jì)算機(jī)里的存儲(chǔ)問(wèn)題了。
3、數(shù)據(jù)存儲(chǔ)與計(jì)算
在計(jì)算之前,我們要先了解數(shù)據(jù)在計(jì)算機(jī)中的存儲(chǔ)問(wèn)題。
計(jì)算機(jī)內(nèi)部在做數(shù)學(xué)運(yùn)算時(shí)(也就是計(jì)算機(jī)的0和1的運(yùn)算),都是以補(bǔ)碼為標(biāo)準(zhǔn)的,說(shuō)白了 計(jì)算機(jī)中就一種碼那就是補(bǔ)碼,而現(xiàn)實(shí)社會(huì)中的編碼規(guī)則,例如原碼、反碼都是我們自定義的,為了和計(jì)算機(jī)中的補(bǔ)碼形成轉(zhuǎn)換關(guān)系。
所以說(shuō)在我們手工計(jì)算這類由計(jì)算機(jī)計(jì)算的01運(yùn)算,要站在計(jì)算機(jī)的角度。因此首先就要將我們的原碼反碼什么的全都先轉(zhuǎn)為補(bǔ)碼,再來(lái)計(jì)算,這樣才能使得正數(shù)和負(fù)數(shù)的表示統(tǒng)一起來(lái)。
3.1、求補(bǔ)碼
那么,正數(shù)和負(fù)數(shù)的補(bǔ)碼如何求呢?這里我們以7和-7為例來(lái)討論下正數(shù)和負(fù)數(shù)求補(bǔ)碼的方法。
3.1.1、正數(shù)補(bǔ)碼
正數(shù)的原、反、補(bǔ)碼都是它本身;這是一條定理,所以直接使用就ok。
因此7的補(bǔ)碼就是:
0000 0000 0000 0000 0000 0000 0000 0111
這里我們可以簡(jiǎn)寫成:0000 0111
3.1.2、負(fù)數(shù)補(bǔ)碼
這里我們分兩種情況,一種是求十進(jìn)制負(fù)數(shù)的補(bǔ)碼,一種是正數(shù)取反后獲得的二進(jìn)制負(fù)數(shù)的補(bǔ)碼。
3.1.2.1、十進(jìn)制負(fù)數(shù)求補(bǔ)碼
規(guī)則:負(fù)數(shù)的絕對(duì)值取反后,+1
以-7為例:
|-7| = 7
原碼
|
0000
|
0111
|
取反
|
1111
|
1000
|
+1
|
1111
|
1001
|
所以得到-7的補(bǔ)碼就是:
1111 1001
這就是-7在計(jì)算機(jī)中的表現(xiàn)形式。
3.1.2.2、二進(jìn)制負(fù)數(shù)求補(bǔ)碼
規(guī)則:保持符號(hào)位不變,其他位取反后,+1
以(1111 1000)為例:
原碼
|
1111
|
1000
|
取反
|
1000
|
0111
|
+1
|
1000
|
1000
|
*紅色字體代表的是負(fù)數(shù)的符號(hào)位。
因此二進(jìn)制負(fù)數(shù) 1111 1000的補(bǔ)碼就是:
1000 1000
有了補(bǔ)碼之后我們就要去做取反操作了。
3.2、取反
|
7
|
-7
|
計(jì)算機(jī)中補(bǔ)碼形式
|
0000 0111
|
1111 1001
|
取反
|
1111 1000
|
0000 0110
|
結(jié)果類型
|
負(fù)數(shù)
|
正數(shù)
|
結(jié)果要以補(bǔ)碼形式存儲(chǔ)
|
結(jié)果原碼 1111 1000
結(jié)果反碼 1000 0111
結(jié)果補(bǔ)碼 1000 1000
|
結(jié)果原碼 0000 0110
結(jié)果反碼 0000 0110
結(jié)果補(bǔ)碼 0000 0110
|
結(jié)果十進(jìn)制數(shù)
|
-8
|
6
|
*紅色字體代表的是負(fù)數(shù)的符號(hào)位。
取反總結(jié)
-
取反:正數(shù)變負(fù)數(shù),負(fù)數(shù)變正數(shù)
-
取反后,如果結(jié)果為負(fù)數(shù),要計(jì)算它的補(bǔ)碼,根據(jù)計(jì)算出的補(bǔ)碼得到最后的十進(jìn)制結(jié)果。
-
取反后,如果為正數(shù),則其原碼、反碼、補(bǔ)碼一樣,因此,可以直接計(jì)算出十進(jìn)制結(jié)果。
取反使用的定理
-
二進(jìn)制正數(shù)的原碼、反碼、補(bǔ)碼都一樣
-
二進(jìn)制負(fù)數(shù)的在計(jì)算機(jī)中采用補(bǔ)碼的方式表示,所以遇到負(fù)數(shù)先求補(bǔ)碼。
3.3、取反公式
前輩們?cè)诖罅繉?shí)驗(yàn)的基礎(chǔ)上總結(jié)出了取反的計(jì)算公式:
~x = -(x+1)
大家可以使用這個(gè)公式去驗(yàn)證一下自己的計(jì)算結(jié)果是否正確。
4、總結(jié)計(jì)算流程
4.1、正數(shù)取反
步驟一:按位取反
步驟二:結(jié)果為負(fù)數(shù),求結(jié)果補(bǔ)碼(方法:負(fù)數(shù)符號(hào)位不變,其他位取反,然后+1)
步驟三:得到結(jié)果,計(jì)算出十進(jìn)制結(jié)果
4.2、負(fù)數(shù)取反
步驟一:先求補(bǔ)碼(方法:絕對(duì)值的二進(jìn)制形式取反,然后+1)
步驟二:得到補(bǔ)碼,即負(fù)數(shù)在計(jì)算機(jī)中的表現(xiàn)形式,然后取反
步驟三:得到正數(shù),直接計(jì)算十進(jìn)制結(jié)果
相信到這里,大家對(duì)取反操作的計(jì)算都明白了吧?趕緊去驗(yàn)證一波吧!
如果想要獲取更多嵌入式相關(guān)課程信息及學(xué)習(xí)資料,可以咨詢課程顧問(wèn)老師:高老師(18925216388)