以前經常看到帶符號的char類型取值范圍是-128——127,今天突然想為什么不是-127——127,-128是怎么來的?
127好理解,char類型是8位,最高位是符號位,0正1負,所以01111111是127。
但是-128是怎么來的呢?11111111不是-127嗎?
后來想起來計算機里面所有數都是用補碼表示的,正數補碼是其本身,負數補碼是原碼的反碼加1。
所以-127是10000001,而10000000換算過來就是-128。
所以, 8位有符號的整數取值范圍的補碼表示
1000 0000 到 0000 0000, 再到 0111 1111
即 -128 到 0, 再到 127
最終 -128 ~ +127
補充說明
“一個n位有符號int型數值,其范圍為-2^(n-1) ——2^(n-1) -1”,對於這個問題,很多人都是困惑不已。其實,導致此情況的根本原因是“人們解決問題時,習慣以人的思維思考問題,但是,計算機本身確實以機器的思維進行處理的”。在這里,就表現為“計算機對數據的處理其實是以‘補碼’的形式,而非日常生活中人們進行數學運算所采用的‘原碼’的形式”,但是,人們在對“此數值范圍”進行處理的時候,卻習慣性的采用了“原碼作為機器碼”。
在歷史上,針對“數值”計算,計算機先后采用過3種機器碼——原碼、反碼和補碼。
具體表示如下:
1. 原碼 最高位為符號位,其余為對應數值的絕對值的二進制數值表示;
2. 反碼 最高位為符號位,正數=原碼 負數=符號位+原碼對應的其他位數取反;
3. 補碼 最高位為符號位,正數=原碼 負數=反碼+1。
其中,符號位“0為+,1為-”。
因為,計算機為數據類型分配了n位,超過n位的數值會被自動舍棄,那么, 就可以發現,現在計算機系統中采用的補碼,克服了“原碼中存在+0和-0”的情況,僅表現為一個0,(對於8位數據類型,即為8個0,具體推導見轉載內容的窮舉,-128計算補碼時,產生的9位數據11000 0000--補碼1000 0000)。
對應而言,8位有符號位數值的范圍就成為了“-2^(8-1) ——2^(8-1) -1”,即“-128——+127”。
問題的關鍵就在這里了,“計算機為有符號int型數值分配固定的位數n存儲數據,當數據位數大於n時,大於n的位數被自動舍棄”。這就是導致數值范圍為“-2^(n-1) ——2^(n-1) -1”的原因,從而,也導致了數據范圍中“模”概念的產生。
注:
1. 模
“模”實質上是計量器產生“溢出”的量,它的值在計量器上表示不出來,計量器上只能表示出模的余數。例如,雖然時鍾的模=12,但是在時鍾的指針並不能真正指向“12點”,“12點”的位置和“0點”是重合的,即12點以0點表示。
換句話說,時鍾的范圍“0——11”,則模為12。
對應而言,n位無符號數值的計量范圍0~2^(n)-1,模=2^(n); n位有符號數值,數值范圍-2^(n-1) ——2^(n-1) -1,則模為2^(n-1)。舉例說明,8位無符號數值,二進制模為2^8;8位有符號數值,表示的數值范圍為0——2^8-1。
2. 補碼的運算規則
[X+Y]補 = [X]補 + [Y]補 ;[X-Y]補 = [X]補 - [Y]補 = [X]補 + [-Y]補。
轉自:http://blog.csdn.net/huang_jinjin/article/details/7420545
