1. 程式人生 > >現在的C語言編輯器裡的int範圍為什麼是-2147483648~2147483647

現在的C語言編輯器裡的int範圍為什麼是-2147483648~2147483647

下面是引用百度文庫的一段話:

“這得從二進位制的原碼說起: 

如果以最高位為符號位,二進位制原碼最大為0111111111111111=215-1=32767 最小為1111111111111111=-(215-1)=-32767 
此時0有兩種表示方法,即正0和負0:0000000000000000=1000000000000000=0 
所以,二進位制原碼錶示時,範圍是-32767~-0和0~32767,因為有兩個零的存在,所以不同的數值個數一共只有216-1個,比16位二進位制能夠提供的216個編碼少1個。 但是計算機中採用二進位制補碼儲存資料,即正數編碼不變,從0000000000000000到
0111111111111111依舊錶示0到32767,而負數需要把除符號位以後的部分取反加1,即-32767的補碼為1000000000000001。 
到此,再來看原碼的正0和負0:0000000000000000和1000000000000000,補碼錶示中,前者的補碼還是0000000000000000,後者經過非符號位取反加1後,同樣變成了
0000000000000000,也就是正0和負0在補碼系統中的編碼是一樣的。但是,我們知道,16位二進位制數可以表示216個編碼,而在補碼中零的編碼只有一個,也就是補碼中會比原碼多一個編碼出來,這個編碼就是1000000000000000,因為任何一個原碼都不可能在轉成補碼時變成1000000000000000。所以,人為規定1000000000000000這個補碼編碼為-32768。 所以,補碼系統中,範圍是-32768~32767。 

因此,實際上,二進位制的最小數確實是1111111111111111,只是二進位制補碼的最小值才是1000000000000000,而補碼的1111111111111111是二進位制值的-1。 ”

因為當時的計算機普遍是16位,而現在的計算機普遍32位,所以上面的結論也就相應的變成了-2的31次方到2的31次方。這樣的話範圍是-2147483647~2147483647 但是由於人為規定的100000…000(31個0)為-2147483648,所以範圍就變成了-2147483647~2147483647 。

下面再講一下關於算術溢位的問題的問題,溢位就是取模。弄懂了原碼、補碼的概念後,會發現其實都是有規律可循的。比如-1強制轉換成unsigned int 後是4294967295.

int的範圍是:-2147483648~2147483647 unsigned int的範圍是:0~4294967295。如果超出這個範圍會出現迴圈比如-2147483648-1=2147483647;4294967295+1=0;

也可以堪稱是取模後的說,比如int的模是 2147483648(2的31次方)。unsigned int的模是4294967296(2的32次方);比如4294967297%4294967296=1(與超出範圍得到的結果相同4294967297超出2所以-1+2=1);

計算機的處理方式真的很神奇,這樣最大的數+1變成了最小的數,最小的數-1又成了最大的數。所有的數都連成了一個圓環。

要注意的是-2147483648這個數雖然是int的下限,但是計算機在處理的時候先是2147483648再加上一個-運算子,但是2147483648這一步的時候已經超出的int的範圍,所以它比較特殊,直接賦值int a=-2147483648VC會有警告,(處理辦法是int a=-2147483647-1就沒警告了,或者是呼叫#include<Limits.h>裡的常量INT_MIN)