unsigned y = 1; int x = -2; cout << x + y << endl;
對於上述的結果為
這里面有一個負數的補碼問題和不同類型之間的隱式類型轉換問題
首先負數的表示方法是負數的絕對值的二進制碼取反再加1,-2的補碼計算就是:
0000 0000 0000 0010->1111 1111 1111 1101->1111 1111 1111 1111 1110
而整數的加減在內部都是通過加運算實現的,主要原因是使用補碼,可以將符號位和其它位統一處理;同時,減法也可按加法來處理。另外,兩個用補碼表示的數相加時,如果最高位(符號位)有進位,則進位被舍棄。
1的二進制表示是:0000 0000 0000 0001
x + y在內部的二進制表示就是1111 1111 1111 1111
對於最后的類型又有一個隱式類型轉換的規則,兩個通用的指導原則如下:
1、為防止精度損失,如果必要的話,類型總是被提升為較寬的類型。
2、所有含有小於整形的有序類型的算術表達式在計算之前其類型都會被轉換成整形。
一般來說各種類型的轉換順序為 long double > double > float >= int >= short > char,unsigned > signed 。
由於unsigned > signed,所以x+y被解釋為unsigned,最后輸出值就是2的32次方減一
int取值范圍
-2^31 ~ 2^31-1
為什么負數是 -2^31 而不是-2^31-1呢?
因為規定了1000 0000, 0000 0000, 0000 0000, 0000 0000這個特殊的數(本來是-0的)為-2^31,所以負數就多一個
同理char類型的取值范圍為-128到127,在這里也是把1000 0000表示為-128