C語言 有符號整型 補碼表示的小陷阱

2021-06-09 23:49:59 字數 2091 閱讀 9513

幾乎所有的 c語言 入門書籍都會在 最前面的章節裡 介紹 資料型別,而且基本都是從 整型 開始(至少我看過的基本都是這樣)。不過對這個東西的運用,似乎很多人(包括我)都是粗略的看看就過去了。這裡我說一下乙個小小的陷阱,姑且算是吧。

c語言標準 要求 這些資料型別必須 至少有這樣的取值範圍。

即,實際上可以放大範圍,只要 型別的取值範圍 包含 表中定義的範圍即可。

c 資料型別

minmax

char

-127

127unsigned char

0255

short int

-32,767

32,767

unsigned short int

065,535

int-32,767

32,767

unsigned int

065,535

long int

-2,147,483,647

2,147,483,647

unsigned long int

04,294,967,295

long long int

-9,223,372,036,854,775,807

9,223,372,036,854,775,807

unsigend long long int

018,446,744,073,709,551,615

首先看無符號整數,還是比較好理解的,對於佔w位的整型,最大能表示的值為2w - 1(w個1),最小淡然是0了。如果把這個位串看成乙個向量,最右邊的記為第 0 位,最左邊的為 第w - 1 位,則對第i位上的數x[ i ](1 or 0),代表的數 即為 x[ i ] * 2i,將這w個值加起來就是此位串表示的數值(很多人應該都知道,就不多說了),

value ==> x[ w-1 ] * 2

w-1+ x[ w-2] * 2

w-2+ ··· + x[ 0 ] * 20。

但是 有符號整數就比較蛋疼了。因為實際上,絕大多數 機器都採用 補碼形式表示有符號整數,即最高位(位串中的第w - 1位)表示權值取負值,

value==>-x[ w-1 ] * 2w-1

+ x[ w-2] * 2w-2 + ··· + x[ 0 ] * 20。

按照c語言標準來講,正負區間是對稱的。而採用補碼的計算機,若只看最高位,1表示負數,0表示正數,則根據那個什麼排列組合來看,也正好一半對一半吧。

不過可惜,上面說錯了,當最高位是0,其餘的位也都是0的情況下,表示的是整數 0,不是正數,也不是負數。因此正數比負數要 少乙個,【10000.....000】(即, -2w-1)沒有對應的正數。最大的正數是【0111111...111111】(即, 2w-1 - 1)。這就是補碼的取值區間(最大正數的絕對值 比 最小負數的絕對值 少 1)。

當然,我們最關心的還是這個對我們有什麼影響。我沒有什麼專案經驗,就平時自己寫點東西,所以也不是很清楚,就不丟這個人了<-_-·>。不過例子倒是有乙個。

#include #include int main(void)

// end main.

當你對乙個正數取負值時,恰好這個數是 該整型的 最小負值,加個負號和沒加是一樣的。

那這又怎麼樣呢? 反正就是**沒能按照我們的意願去執行,而且估計在大專案裡也很難發現吧。

採用補碼形式表示有符號整數的計算機: 

至於有什麼好的解決辦法嘛,我這個菜鳥也沒什麼好說的。我給自己的建議是:在c程式中使用整型的時候,注意值的表示範圍吧,當可能出現這種 "極限" 情況的時候,選取可以表示更大範圍整數的型別吧

另外,就算不是為了相容性,保證只使用c語言標準中給出的數值範圍應該算個好習慣吧。

8位有符號數的補碼表示範圍

範圍是 128至127.根據補碼的幾條規定即可推出上述結論 1 若二進位制每位全為0,則表示數0 2 若最高位 即符號位 為0,表示正數 3 若最高位為1,表示是負數,而該負數的絕對值是多少呢?將每個二進位制位 包括符號位 取反加1,得到乙個二進位制數,將該數看成無符號數,其值就是上述負數的絕對值。...

如何計算乙個有符號數的補碼表示?

按照 譚浩強.c程式設計 第三版 北京 清華大學出版社,2005 的第40頁至第41頁所述,求乙個負數的補碼的方法如下 例 求 10的補碼的方法如下 1 取 10的絕對值10 2 10的絕對值的二進位制形式為1010 3 對1010取反得1111 1111 1111 0101 這裡假定乙個整數佔16...

C 11 有符號整型與無符號整型的比較運算

在執行讀取操作的時候,使用cin str string物件會自動忽略開頭的空白,並從第乙個真正的字元開始讀取,直到遇見下乙個空白,但是getline cin,str 函式不會忽略空白,而是自動讀取一行的所有值,直到換行符出現,並且將換行符也讀入了,然後把所讀去的內容存到string物件去 注意不存在...