C語言 1字節signed char的范圍為什么是-128~127?


參考

1. 關於 -128 ,+128,-0,+0,-1 的反碼補碼 | 博客園

2. 八位二進制數為什么表示范圍(-128~~+127)理解 | 博客園

 

無符號單字節范圍

無符號單字節unsigned char位寬是8bit,范圍[0, 1111 1111b],也就是[0, 255]。

 

有符號單字節范圍

有符號單字節signed char位寬也是8bit,絕對值范圍也是[0, 1111 1111b],不過最高位表示符號位,能表示的范圍是多少呢?

不得不考慮一個特殊情況,0加符號位可表示+0,-0。而在早期計算機存儲不夠時,用2個不同的補碼(±0)表示數學上的同一個0,是一種浪費,故規定-0表示為-128。

這樣,[-127, 127](補碼:[1000 0001b, 0111 1111b])就沒有爭議。

我們知道,

-128 = -127 - 1,那么,補碼=1000 0001b - 1b = 1000 0000b ,最高位1,符號位未變;

128 = 127 + 1,那么,有兩種情況

1)反碼+1到補碼符號位改變,補碼=0111 1111b + 1b = 1000 0000b,最高位1,與-128補碼相同。

2)反碼+1到補碼符號位不可變,補碼=0111 1111b + 1b = 0000 0000b, 最高位為0,與+0補碼相同。 (不符合溢出特點,因為+0不是最小的數,最大的數溢出后一般成為最小的數,舍)

由此,+128(若存在)及-128的補碼,和-0原碼是一樣的。

 

那么,-128在計算機中實際上是如何用單字節存儲的?

下面做實驗驗證,思路:用單字節signed char存儲,然后直接debug查看存儲的二進制值。

(調試環境:IDE Eclipse Photon,編譯器:Cygwin GCC)

#include <stdio.h>

int main()
{
	signed char a = -128;
	signed char a2= -127;
	signed char a3 = 128;

	int na = sizeof(a);
	int na2 = sizeof(a2);
	int na3 = sizeof(a2);

	printf("a=%d , size=%d\n", a, na);
	printf("a2=%d , size=%d\n", a2, na2);
	printf("a3=%d , size=%d\n", a3, na3);

	a --;
	a2 --;
	a3 ++;
	printf("a=%d , size=%d\n", a, na);
	printf("a2=%d , size=%d\n", a2, na2);
	printf("a3=%d , size=%d\n", a3, na3);
	return 0;
}

 

可以發現,

a=-128 (Decimal)= 1000 0000 (Binary)

a=-127 (Decimal)= 1000 0001 (Binary)

a=+128 (Decimal),但計算機存儲值=-128(Decimal)=1000 0000 (Binary)

 

 a, a2, a3自減1后,

a = 0111 1111(Binary) = 127 (Decimal)

a2 = 1000 0000(Binary) = -128(Decimal)

a3 = -127(Decimal)

 

對應Console輸出

 

小結

1. 計算機中,C語言有符號單字節表示范圍[-128, 127]

2. 無法直接存儲128,會轉換為-128

 


免責聲明!

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



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