在32位系統中,int型別佔4個位元組,一共是32個2進製位,int型別的首位是符號位,0代表正數,1代表負數,int的最大值是0x7fffffff(即除了最高的1bit其他31位都為1),而最小值是0x80000000(除了最高1bit,其他31位都為0)。但是我有幾個問題,在這裡記錄解答一下
關於補碼
計算機中的補碼是為了方便負數方便運算而設定的,因為如果直接相加,結果是不正確的,正數的補碼是其自身,而負數的補碼是取其反碼。注意,負數實際上是按照補碼儲存在計算機中的
舉兩個例子:
-5 + 6
-5 = 1101 (第一位是符號位)
-5的補碼為1010 + 1 = 1011
6 = 0110
二者相加1011 + 0110 = 10001 = 0001 = 1 = (-5)+ 6結果是正確的
再看乙個例子
-6 + 5
-6 = 1110 補碼為 1001+1 = 1010
5 = 0101
-6 + 5 = 1010 + 0101 = 1111
這裡的1111,注意顯示的是負數的補碼,所以要得到正確值,需要轉換為原碼
1111 => 1110 =>取反後得到,1001 => -1
為什麼正負數的絕對值大小不一樣
首先我很奇怪就是,在計算機語言中,int型別的最大值是01111111…1111(31個1),這個很容易理解,因為0是符號位,所以int的最大值是2147483647,按照這個邏輯,那麼負數的值應該為1111111…111(32個1),第乙個1是符號位,那麼int的最小值不應該是-2147483647麼,而實際上int的最小值是-2147483648,這是為什麼呢?
為了解答這個問題,首先回到上述概念,可以發現,由於32位的int前面有一位符號位,那麼如果按照之前的邏輯,那麼1000000…000(31個0)和000…000(32個0),也就是正0和負0,不是一樣的麼?根據我的理解,為了不讓資料浪費,規定,負0作為int型別的最小值,也就是-1 * 2^31
,所以int型別範圍在- 2^31
到2^31 - 1
之間
int型別的最大值加一後,會變為最小值
可以先看乙個**的例子:
int main()
{ int a = 0x80000000;
int b = 0x7fffffff;
std::cout << "mininteger: " << a << std::endl;
std::cout << "mininteger - 1: " << a - 1 << std::endl;
std::cout << "maxinteger: " << b 輸出結果如下:
可以看到,最大值+1變為了最小值,最小值-1變為了最大值,根據上面講的補碼的知識,我們可以分析一下:
在計算機中,max和min對應的值分別為:
0111 1111 1111 1111 1111 1111 1111 1111 : max interger = 2^31 - 1
1000 0000 0000 0000 0000 0000 0000 0000:min interger = - 2^31
但是實際計算時是按照補碼來的,所以其補碼為:
0111 1111 1111 1111 1111 1111 1111 1111 : max interger = 2^31 - 1
1000 0000 0000 0000 0000 0000 0000 0000:min interger = - 2^31,我們發現最小值的補碼與其原碼相同
ok,那麼我們開始計算,首先計算max + 1:
0111 1111 1111 1111 1111 1111 1111 1111 // max
0000 0000 0000 0000 0000 0000 0000 0001
---------------------------------------
1000 0000 0000 0000 0000 0000 0000 0000
可以看到結果正好為最小值
再計算min - 1
1000 0000 0000 0000 0000 0000 0000 0000 // min
1111 1111 1111 1111 1111 1111 1111 1111 // -1的補碼
---------------------------------------
0111 1111 1111 1111 1111 1111 1111 1111 // 最高位溢位
所以說,了解了底層補碼是怎麼設計的,上述問題自然就能夠得到解釋。
為什麼這麼設計
主要是基於以下幾點:
更多細節可以參考:
計算機表示正負數
國內很多教材都有其為本科教材,對於計算機表示負數大概只有一句話,取反加一 並稱之為 補碼 今天偶然翻閱資料,覺得是時候徹底解決一下這個問題了。首先 二進位制補碼 只是人為定義的乙個概念,與 黃赤交角 一樣。不是在說明問題的本質,而是在解釋解決問題的辦法。計算機表示負數,運用的是 溢位原理 溢位原理,...
計算機中負數表示法
問乙個基本的問題。負數在計算機中如何表示?舉例來說,8在計算機中表示為二進位制的 1000 那麼 8 怎麼表示呢?很容易想到,可以將乙個二進位制位 bit 專門規定為符號位,它等於 0時就表示正數,等於 1時就表示負數。比如,在 8位機中,規定每個位元組的最高位為符號位。那麼,8就是 0000100...
對計算機中負數表示的思考
我們都知道計算機中負數用補碼表示,即 取反 加1,那為什麼這麼蛋疼的表示呢,既然要區分正負數,直接用最高位來區分不就行了嗎?仔細思考了下,負數用補碼表示是為了實現加法和減法的統一 更確切說就是為了實現減法 設要表示的整數 i 由 b 位儲存,那麼 i 2 b 1。下面討論均是整數。設有一正整數i1,...