關於補碼中為什么1000 0000 代表的是-128的值


前言:學校里課程需要,所以接下來一直在補數電和計算機組成原理,所以這里作筆記

參考文章:https://blog.csdn.net/github_36186488/article/details/72461416
參考文章:https://blog.csdn.net/Neutionwei/article/details/108180243

補碼的由來:想要實現將符號位參與運算, 並且只保留加法的方法,通過補碼的編碼方式,能夠成功的解決計算機中的運算結果和邏輯的運算結果相符合。

其實對於原碼/補碼/反碼,自己不理解的最大地方可能就是為什么1000 0000 在補碼編碼方式中代表的是-128這個值,自己這篇筆記就詳細的來說這個東西。

補碼的優點

1、0的表示唯一(為什么呢,因為如果通過原碼的表示方法的話,那么就會存在+0 和-0的存在, +0 -> 0000 0000 -0 -> 1000 0000)。

2、運算更加符合邏輯,如0-1=-1,補碼表示的二進制算法00000000-00000001=11111111,結果相同。

3、上溢與下溢(重點理解)

上溢:如果你對signed char類型所能表示的最大的數字再加一,就會產生上溢,例如+127+1, 使用補碼運算可得01111111+00000001 = 10000000,得到的結果為-128,這樣的結果也是比較有邏輯性的,可以接受。

下溢:如果你對signed char類型所能表示的最小的數字減一,就會產生下溢,例如-128-1,使用補碼運算可得10000000-00000001 = 01111111,得到的結果為+127。這里面的邏輯是:補碼使得一個類型所能表示的所有數字構成了一個環,以signed char為例就是下面的情形

上溢與下溢

我這里詳細的記錄“上溢與下溢”相關的內容

這個“上溢與下溢”來講述為什么在補碼的編碼方式中,1000 0000 代表的是-128,說到底其實就是為了計算機底層的運算所規定的規則。

這里先來講上溢,來把上面的關於上溢的定義拿過來

上溢:如果你對signed char類型所能表示的最大的數字再+1,就會產生上溢,例如+127+1, 使用補碼運算可得01111111+00000001 = 10000000,得到的結果為-128,這樣的結果也是比較有邏輯性的,可以接受。

我這里用C語言來演示下,首先需要知道的在計算機的數據存儲中用到的都是補碼的編碼方式,然后我寫下如下的代碼來進行演示

int main()
{
	// 上溢:如果你對char類型所能表示的最大的數字再 + 1,就會產生上溢,例如 + 127 + 1, 使用補碼運算可得01111111 + 00000001 = 10000000,
	// 得到的結果為 -128,這樣的結果也是比較有邏輯性的,可以接受。
	signed char a = 128; // 2^7 = 128
	printf("%d", a);

	return 0;
}

結果如下,可以看到有符號位的char類型,當其a變量的值為128的時候,打印出來的確是-128的值,這里同樣也說明了“上溢”,其實就是進位了,如果大家調試過的話就會發現其中的OF標志寄存器(溢出標志位)會被置為1,則表示進位。

繼續來講下什么是下溢,演示代碼如下,對於有符號為的數來說,-128其實是char類型中最小的數了,如果該值127的話,那么就會

int main()
{	
	// 下溢:如果你對signed char類型所能表示的最小的數字減一,就會產生下溢,例如-128-1,使用補碼運算可得10000000-00000001 = 01111111,
	// 得到的結果為+127。這里面的邏輯是:補碼使得一個類型所能表示的所有數字構成了一個環,以signed char為例就是下面的情形
	signed char a = -128-1;
	printf("%d", a);

	return 0;
}

再來理解下這張圖即可

有符號位和無符號位的運算

所以這里順帶記錄下

這里的話,自己同樣以調試來給大家展示

int main()
{
	unsigned char a = -1;
	signed char b = -1;
	printf("%d", a - b);
	return 0;
}

結果如下:

這里要如何理解?先來看下unsigned 和 signed聲明的-1在內存中都是如何存儲的,可以看到都是0xFF的值

那么這里是如何運算的,首先unsigned聲明的變量為無符號類型,一個無符號的char類型的范圍是多少?[0,255],都是正數,雖然存儲在內存中的都是補碼,但是因為正數,所以原碼=反碼=反碼,這個值其實就是0xFF

繼續來看signed聲明的變量為有符號類型,那么一個有符號的char類型的范圍為[-128,-127],且最高為表示符號位,所以有符號位的-1實際上就是-1這個值

那么最后printf("%d", b + c);,也就是255+(-1),也就是 1111 1111 + 1000 0001 ,那么結果自然就是254

還有一個知識點就是:當表達式中存在有符號類型和無符號類型時所有的操作數都自動轉換為無符號類型。因此,從這個意義上講,無符號數的運算優先級要高於有符號數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM