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>
- 正數(shù):正數(shù)的補(bǔ)碼和原碼相同。
- 負(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