C語言有符號(hào)和無符號(hào)的理解

1.你自已決定是否需要有正負(fù):

就像我們必須決定某個(gè)量使用整數(shù)還是實(shí)數(shù),使用多大的范圍數(shù)一樣,我們必須自已決定某個(gè)量是否需要正負(fù)。如果這個(gè)量不會(huì)有負(fù)值,那么我們可以定它為帶正負(fù)的類型。

在計(jì)算機(jī)中,可以區(qū)分正負(fù)的類型,稱為有符類型(signed),無正負(fù)的類型(只有正值),稱為無符類型。 (unsigned)數(shù)值類型分為整型或?qū)嵭停渲姓陀址譃闊o符類型或有符類型,而實(shí)型則只有符類型。 字符類型也分為有符和無符類型。 比如有兩個(gè)量,年齡和庫存,我們可以定前者為無符的字符類型,后者定為有符的整數(shù)類型。

**2.使用二制數(shù)中的最高位表示正負(fù): **

首先得知道最高位是哪一位?1個(gè)字節(jié)的類型,如字符類型,最高位是第7位,2個(gè)字節(jié)的數(shù),最高位是第15位,4個(gè)字節(jié)的數(shù),最高位是第31位。不同長度的數(shù)值類型,其最高位也就不同,但總是最左邊的那位(如下示意)。字符類型固定是1個(gè)字節(jié),所以最高位總是第7位。

(紅色為最高位)

單字節(jié)數(shù):

<font color=red>1</font>1111111

雙字節(jié)數(shù):

<font color=red>1</font>1111111 11111111

四字節(jié)數(shù):

<font color=red>1</font>1111111 11111111 11111111 11111111

當(dāng)我們指定一個(gè)數(shù)量是無符號(hào)類型時(shí),那么其最高位的1或0,和其它位一樣,用來表示該數(shù)的大小。
當(dāng)我們指定一個(gè)數(shù)量是無符號(hào)類型時(shí),此時(shí),最高數(shù)稱為“符號(hào)位”。為1時(shí),表示該數(shù)為負(fù)值,為0時(shí)表示為正值。

**3.無符號(hào)數(shù)和有符號(hào)數(shù)的范圍區(qū)別: **

無符號(hào)數(shù)中,所有的位都用于直接表示該值的大小。有符號(hào)數(shù)中最高位用于表示正負(fù),所以,當(dāng)為正值時(shí),該數(shù)的最大值就會(huì)變小。我們舉一個(gè)字節(jié)的數(shù)值對(duì)比:

無符號(hào)數(shù): 11111111 值:255

這里寫圖片描述

有符號(hào)數(shù): 01111111 值:127

這里寫圖片描述

eg:(本屌實(shí)在不知道怎么用md語法來打出數(shù)學(xué)公式,2的冪次方)

同樣是一個(gè)字節(jié),無符號(hào)數(shù)的最大值是255,而有符號(hào)數(shù)的最大值是127。原因是有符號(hào)數(shù)中的最高位被挪去表示符號(hào)了。并且,我們知道,最高位的權(quán)值也是最高的(對(duì)于1字節(jié)數(shù)來說是2的7次方=128),所以僅僅少于一位,最大值一下子減半。

不過,有符號(hào)數(shù)的長處是它可以表示負(fù)數(shù)。因此,雖然它的在最大值縮水了,卻在負(fù)值的方向出現(xiàn)了伸展。我們?nèi)砸粋€(gè)字節(jié)的數(shù)值對(duì)比:

<font color=blue size=4>無符號(hào)數(shù): </font> 0 ----------------- 255

<font color=blue size=4>有符號(hào)數(shù): </font> -128 --------- 0 ---------- 127

同樣是一個(gè)字節(jié),無符號(hào)的最小值是 0 ,而有符號(hào)數(shù)的最小值是-128。

所以二者能表達(dá)的不同的數(shù)值的個(gè)數(shù)都一樣是256個(gè)。只不過前者表達(dá)的是0到255這256個(gè)數(shù),后者表達(dá)的

是-128到+127這256個(gè)數(shù)。

一個(gè)有符號(hào)的數(shù)據(jù)類型的最小值是如何計(jì)算出來的呢?

有符號(hào)的數(shù)據(jù)類型的最大值的計(jì)算方法完全和無符號(hào)一樣,只不過它少了一個(gè)最高位(見第3點(diǎn))。但在負(fù)值
范圍內(nèi),數(shù)值的計(jì)算方法不能直接使用1* 26 + 1* 25 的公式進(jìn)行轉(zhuǎn)換。

在計(jì)算機(jī)中,負(fù)數(shù)除為最高位為1以外,還采用補(bǔ)碼形式進(jìn)行表達(dá)。所以在計(jì)算其值前,需要對(duì)補(bǔ)碼進(jìn)行還原。 這里,先直觀地看一眼補(bǔ)碼的形式:

在10進(jìn)制中:1 表示正1,而加上負(fù)號(hào):-1 表示和1相對(duì)的負(fù)值。

那么,我們會(huì)很容易認(rèn)為在2進(jìn)制中(1個(gè)字節(jié)): 0000 0001 表示正1,則高位為1后:1000 0001應(yīng)該表示-1。

然而,事實(shí)上計(jì)算機(jī)中的規(guī)定有些相反,請(qǐng)看下表:

二進(jìn)制(1字節(jié)) 十進(jìn)制值
10000000 -128
10000001 -127
10000010 -126
10000011 -125
10000100 -124
...... ......
11111110 -2
11111111 -1

首先我們看到,從-1到-128,其二進(jìn)制的最高位都是1,正如我們前面說的,負(fù)數(shù)最高位為1,然后我們覺得有點(diǎn)奇怪了,1000 0000 并沒有用來表示 0;而 1000 0001也不是拿來直觀地表示-1,事實(shí)上,-1用1111 1111來表示。
怎么理解這個(gè)問題呢?先問一句是-1大還是-128大?
當(dāng)然是-1大,那么,1111 1111 -1是什么呢? 和現(xiàn)實(shí)中的計(jì)算結(jié)果完全一致。1111 1111 -1=1111 1110,而1111 1110 就是-2,就這樣一直減下去,當(dāng)見到只剩最高位用于表示符號(hào)的1意外,其他低位全為0時(shí),就是最小的負(fù)值,在一字節(jié)中,最小的負(fù)值是1000 0000,也就是-128。
我們以-1位例,來看看不同字節(jié)數(shù)的整數(shù)中,如何表達(dá)-1這個(gè)數(shù);

字節(jié)數(shù) 二進(jìn)制值 十進(jìn)制值
單字節(jié)數(shù) 11111111 -1
雙字節(jié)數(shù) 11111111 11111111 -1
四字節(jié)數(shù) 11111111 11111111 11111111 11111111 -1

可能有些人看到這里,就已經(jīng)混了,為什么呢?1111 1111 有時(shí)表示255,有時(shí)又表示-1?所以我再強(qiáng)調(diào) 前面說的第二點(diǎn),你自己決定一個(gè)數(shù)是有符號(hào)還是無符號(hào)的,寫程序時(shí),指定一個(gè)量是有符號(hào)的,那么當(dāng)這個(gè)量的二進(jìn)制各位上的數(shù)都是1時(shí),它表示的數(shù)就是-1;相反,如果事先聲明這個(gè)量是無符號(hào)的, 此時(shí)它表示的就是該量允許的最大值,對(duì)于一個(gè)字節(jié)的數(shù)來說,最大值就是255。

我們已經(jīng)知道計(jì)算機(jī)中,所有數(shù)據(jù)最終都是使用二進(jìn)制數(shù)表達(dá)。 也已經(jīng)學(xué)會(huì)如何將一個(gè)10進(jìn)制數(shù)如何轉(zhuǎn)換為二進(jìn)制數(shù)。 不過,我們?nèi)匀粵]有學(xué)習(xí)一個(gè)負(fù)數(shù)如何用二進(jìn)制表達(dá)。 比如,假設(shè)有一 int 類型的數(shù),值為5,那么,我們知道它在計(jì)算機(jī)中表示為:

00000000 00000000 00000000 00000101  

5轉(zhuǎn)換成二制是101,不過int類型的數(shù)占用4字節(jié)(32位),所以前面填了一堆0。 現(xiàn)在想知道,-5在計(jì)算機(jī)中如何表示? 在計(jì)算機(jī)中,負(fù)數(shù)以其正值的補(bǔ)碼形式表達(dá)。 什么叫補(bǔ)碼呢?這得從原碼,反碼說起。

原碼:一個(gè)整數(shù),按照絕對(duì)值大小轉(zhuǎn)換成的二進(jìn)制數(shù),最高為為符號(hào)位,稱為原碼。 紅色為符號(hào)位

比如:

00000000 00000000 00000000 00000101  是 5的原碼。                      
10000000 00000000 00000000 00000101  是-5的原碼。
 

反碼: 將二進(jìn)制除符號(hào)位數(shù)按位取反,所得的新二進(jìn)制數(shù)稱為原二進(jìn)制數(shù)的反碼。 正數(shù)的反碼為原碼,負(fù)數(shù)的反碼是原碼符號(hào)位外按位取反。

取反操作指:原為1,得0;原為0,得1。(1變0; 0變1)

<font color=red size=4>正數(shù):正數(shù)的反碼與原碼相同。 </font>
<font color=red size=4>負(fù)數(shù):負(fù)數(shù)的反碼,符號(hào)位為“1”,數(shù)值部分按位取反。 </font>

比如:將10000000 00000000 00000000 00000101除符號(hào)位每一位取反,
得11111111 11111111 11111111 11111010。

這時(shí)候我們稱:11111111 11111111 11111111 11111010 是 10000000 00000000 00000000 00000101 的反碼。

<font color=black size=4>反碼是相互的, </font> 所以也可稱:
11111111 11111111 11111111 11111010 和 10000000 00000000 00000000 00000101 互為反碼。

補(bǔ)碼: 反碼加1稱為補(bǔ)碼。 <font color=red size=4> (如果反碼最后一位是1得話就向前加1)</font>

  1. 正數(shù):正數(shù)的補(bǔ)碼和原碼相同。
  2. 負(fù)數(shù):按照規(guī)則來
    也就是說,要得到一個(gè)數(shù)的補(bǔ)碼,先得到反碼,然后將反碼加上1,所得數(shù)稱為補(bǔ)碼。
    11111111 11111111 11111111 11111010 是 10000000 00000000 00000000 00000101(-5) 的反碼。
    加1得11111111 11111111 11111111 11111011
    所以,-5 在計(jì)算機(jī)中表達(dá)為:11111111 11111111 11111111 11111011。轉(zhuǎn)換為十六

進(jìn)制:0xFFFFFFFB。
再舉一例,我們來看整數(shù)-1在計(jì)算機(jī)中如何表示。
假設(shè)這也是一個(gè)int類型,那么:

1、先取-1的原碼: 10000000 00000000 00000000 00000001
2、除符號(hào)位取反得反碼: 11111111 11111111 11111111 11111110
3、加1得補(bǔ)碼: 11111111 11111111 11111111 11111111

可見,-1在計(jì)算機(jī)里用二進(jìn)制表達(dá)就是全1。16進(jìn)制為:0xFFFFFF。

計(jì)算機(jī)中帶有符號(hào)數(shù)用補(bǔ)碼表示的優(yōu)點(diǎn):

<font color=red size=4>1、負(fù)數(shù)的補(bǔ)碼與對(duì)應(yīng)正數(shù)的補(bǔ)碼之間的轉(zhuǎn)換可以用同一種方法——求補(bǔ)運(yùn)算完成,可以簡化硬件;
2、可將減法變?yōu)榧臃ǎ∪p法器;
3、無符號(hào)數(shù)及帶符號(hào)數(shù)的加法運(yùn)算可以用同一電路完成。 </font>

可得出一種心算求補(bǔ)的方法——從最低位開始至找到的第一個(gè)1均不變,符號(hào)位不變,這之間的各位“求反”(該方法僅用于做題)

方法 例子1 列子2
1,從右邊開始,找到第一個(gè)“1” 10101001 10101100
2,從這個(gè)“1”之后開始到最左邊取反(不包括符號(hào)位,也就是最高位) 11010111 11010100

注意:(如果反碼最后一位是1得話就向前加1)

查找資料學(xué)習(xí)理解并整理下來。
希望大家能提出寶貴意見,一起學(xué)習(xí)。
轉(zhuǎn)載請(qǐng)注明出處:http://xuhao.tech/2016/08/07/c/language/signed.html
Blog:xuhao.tech

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容