《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 解決方案 > 計(jì)算機(jī)系統(tǒng)原理(八) C語言的有符號(hào)與無符號(hào),、二進(jìn)制整數(shù)的擴(kuò)展與截?cái)?/span>

計(jì)算機(jī)系統(tǒng)原理(八) C語言的有符號(hào)與無符號(hào),、二進(jìn)制整數(shù)的擴(kuò)展與截?cái)?

2017-06-22
關(guān)鍵詞: 匯編語言

開篇請(qǐng)各位猿友允許LZ啰嗦幾句,最近一直在寫計(jì)算機(jī)系統(tǒng)原理這系列文章,,也已經(jīng)下定決心要把這本書的內(nèi)容寫完,。主要目的其實(shí)是為了鞏固LZ的理解,另外也想把這些內(nèi)容分享給猿友們,,畢竟LZ覺得這些內(nèi)容對(duì)程序猿的實(shí)力還是有著很大的潛在提高的,。

只是這種原理性的文章寫起來相對(duì)復(fù)雜與繁瑣,較對(duì)起來也比較困難,,因?yàn)槲恼吕锍涑庵鞣N各樣的數(shù)學(xué)符號(hào),,不過相對(duì)于這樣的寫作難度來說,其受歡迎程度,,卻遠(yuǎn)遠(yuǎn)比不上一些難度較低的雜文,。這一點(diǎn)從LZ的博客就能很明顯的看出,,LZ博客排名前幾的文章,幾乎全部都是LZ寫的一些雜談,,比如經(jīng)歷,、建議、感悟等等這一類的,。

不過LZ也很理解這種現(xiàn)象,,畢竟雜文看起來不怎么需要?jiǎng)幽X子,內(nèi)容相對(duì)來說也比較有趣,,而且說不定偶爾也能有意外的大收獲,,受歡迎自是無可厚非的。不過對(duì)于計(jì)算機(jī)系統(tǒng)原理這種文章來說,,倘若各位猿友能夠堅(jiān)持看下去的話,,應(yīng)該是會(huì)有不少的收獲的。

此外LZ也希望各位猿友在觀看之余,,也不妨給予LZ一些鼓勵(lì)和支持,,這樣不僅LZ的動(dòng)力會(huì)大大增加,也會(huì)由于猿友們的鼓勵(lì)而產(chǎn)生更大的責(zé)任感,,從而更加費(fèi)心的將內(nèi)容更簡單的解釋清楚,。

廢話就到此結(jié)束吧,再寫下去的話估計(jì)有猿友要忍不住吐槽LZ廢話連篇了,。就此打住,,其實(shí)說了這么多,LZ就是想說五個(gè)字,,“點(diǎn)個(gè)推薦吧,。”

引言

在上一章中,,我們著重介紹了整數(shù)的表示方式,,也就是無符號(hào)編碼和補(bǔ)碼編碼。本次我們來看一下二進(jìn)制整數(shù)的擴(kuò)展與截?cái)?,這部分內(nèi)容是與C語言掛鉤介紹的,。因此我們首先來簡單的看一下C語言的有符號(hào)數(shù)和無符號(hào)數(shù)。

C語言中的有符號(hào)數(shù)和無符號(hào)數(shù)

有符號(hào)數(shù)和無符號(hào)數(shù)的本質(zhì)區(qū)別其實(shí)就是采用的編碼不同,,前者采用補(bǔ)碼編碼,后者采用無符號(hào)編碼,。

在C語言中,,有符號(hào)數(shù)和無符號(hào)數(shù)是可以隱式轉(zhuǎn)換的,不需要手動(dòng)實(shí)施強(qiáng)制類型轉(zhuǎn)換,。不過也正是因?yàn)槿绱?,可能你不小心將一個(gè)無符號(hào)數(shù)賦給了有符號(hào)數(shù),,就會(huì)造成出乎意料的結(jié)果,就像下面這樣,。

#include <stdio.h>
   
int main(){
   short i = -12345;
   unsigned short u = i;
   printf("%d %d\n",i,u);
}


一個(gè)不小心,,一個(gè)負(fù)數(shù)就變成正數(shù)了,再看下面這個(gè)程序,,它展示了在進(jìn)行關(guān)系運(yùn)算時(shí),,由于有符號(hào)數(shù)和無符號(hào)數(shù)的隱式轉(zhuǎn)換所導(dǎo)致的違背常規(guī)的結(jié)果。

#include <stdio.h>
   
int main(){
   printf("%d\n",-1 < 0U);
   printf("%d\n",-12345 < 12345U);
}


可以看到,,兩個(gè)結(jié)果都為0,,也就是false,這與我們直觀的理解是違背的,,原因就是因?yàn)樵诒容^的過程中,,有符號(hào)數(shù)被隱式的轉(zhuǎn)換成了無符號(hào)數(shù)進(jìn)行比較。

擴(kuò)展

當(dāng)我們將一個(gè)短整型的變量轉(zhuǎn)換為整型變量時(shí),,就涉及到了位的擴(kuò)展,,此時(shí)由兩個(gè)字節(jié)擴(kuò)充為四個(gè)字節(jié)。

在進(jìn)行位的擴(kuò)展時(shí),,最容易想到的就是在高位全部補(bǔ)0,,也就是將原來的二進(jìn)制序列前面加入若干個(gè)0,也稱為零擴(kuò)展,。還有一種方式比較特別,,是符號(hào)擴(kuò)展,也就是針對(duì)有符號(hào)數(shù)的方式,,它是直接擴(kuò)展符號(hào)位,,也就是將二進(jìn)制序列的前面加入若干個(gè)最高位。

對(duì)于零擴(kuò)展來說,,很明顯擴(kuò)展之后的值與原來的值是相等的,,而對(duì)于符號(hào)擴(kuò)展來說,則是一樣,,只不過沒有零擴(kuò)展來的直觀,。我們?cè)谟?jì)算補(bǔ)碼時(shí)有一個(gè)比較簡單的辦法,就是符號(hào)位若為0,,則與無符號(hào)是類似的,。若符號(hào)位為1,也就是負(fù)數(shù)時(shí),,可以將其余位取反最終再加1即可,。因此當(dāng)我們對(duì)一個(gè)有符號(hào)的負(fù)數(shù)進(jìn)行符號(hào)擴(kuò)展時(shí),前面加入若干個(gè)1,,在取反之后都為0,,因此依舊會(huì)保持原有的數(shù)值,。

總之,在對(duì)位進(jìn)行擴(kuò)展時(shí),,是不會(huì)改變?cè)袛?shù)值的,。

在書中對(duì)于負(fù)數(shù)的符號(hào)擴(kuò)展還給出了這一過程的證明,LZ這里就不多做敘述了,,其實(shí)這個(gè)證明很簡單,,就是利用了補(bǔ)碼編碼的公式而已。需要多提一句的是,,這里使用了歸納法證明,,因此這里只是擴(kuò)展了一位,具體過程如下,。

截?cái)?/p>

截?cái)嗯c擴(kuò)展相反,,它是將一個(gè)多位二進(jìn)制序列截?cái)嘀凛^少的位數(shù),也就是與擴(kuò)展是相反的過程,。

根據(jù)我們的直觀判斷也不難發(fā)現(xiàn),,截?cái)嗫赡軙?huì)導(dǎo)致數(shù)據(jù)的失真。對(duì)于無符號(hào)編碼來說,,截?cái)嗪缶褪鞘S辔粩?shù)的無符號(hào)編碼數(shù)值,。在書中給出了這一簡單過程的證明,它主要是想表明截?cái)嗲芭c截?cái)嗪蟮臄?shù)值的關(guān)系是取模所得到的,。


對(duì)于補(bǔ)碼編碼來說,,截?cái)嗪蟮亩M(jìn)制序列與無符號(hào)編碼是一樣的,因此我們只需要多加一步,,將無符號(hào)編碼轉(zhuǎn)換為補(bǔ)碼編碼就可以了,。

因此對(duì)于無符號(hào)編碼和補(bǔ)碼來說,可以得到以下兩個(gè)公式,。

其它語言中的有符號(hào)與無符號(hào)

從上面的分析不難看出,,具有有符號(hào)和無符號(hào)數(shù)的語言,可能會(huì)因此引起一些不必要的麻煩,,而且無符號(hào)數(shù)除了能表示的最大值更大以外,,似乎并沒有太大的好處。因此有很多語言是不支持無符號(hào)數(shù)的,。

比如LZ所使用的Java語言,,就只有有符號(hào)數(shù),這樣省去了很多不必要的麻煩,。無符號(hào)數(shù)很多時(shí)候只是為了表示一些無數(shù)值意義的標(biāo)識(shí),,比如我們的內(nèi)存地址,此時(shí)的無符號(hào)數(shù)就有點(diǎn)類似于數(shù)據(jù)庫主鍵或者說鍵值對(duì)中的鍵值的概念,僅僅是一個(gè)標(biāo)識(shí)而已,。

文章小結(jié)

本文主要闡述了C語言當(dāng)中的有符號(hào)數(shù)和無符號(hào)數(shù),以及低位轉(zhuǎn)高位的擴(kuò)展,、高位轉(zhuǎn)低位的截?cái)噙\(yùn)算,,下一章我們將講解很重要的一節(jié)內(nèi)容,整數(shù)的二進(jìn)制運(yùn)算,。


本站內(nèi)容除特別聲明的原創(chuàng)文章之外,,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn),。轉(zhuǎn)載的所有的文章,、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有,。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者,。如涉及作品內(nèi)容、版權(quán)和其它問題,,請(qǐng)及時(shí)通過電子郵件或電話通知我們,,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失,。聯(lián)系電話:010-82306118,;郵箱:[email protected]