繼續有符號與無符號混合運算

2021-10-22 08:14:06 字數 2382 閱讀 5495

前面記錄一篇,關於有符號與無符號的混合運算,會有一些意想不到的結果

那麼,我們是否可以「負負得正」呢?

什麼情況下是不行的?

首先,不要被繞暈。

這是前提: 所有的無符號與有符號運算,都是先轉成無符號運算的。結果返回 無符號,

那麼,理論結果如果本身就是正數的,那實際就應該是正常的

如果結果不是正數的,那麼是負數的無符號形式(最高位=1,其他位取反)

為了驗證效果,(就驗證加/減/乘/除),寫段**試試:

int a = -20;

unsigned int b = 10;

//保持原始結果

cout << "a+b=" << a + b << endl; //希望:-10

cout << "a*b=" << a * b << endl; //希望:-200

cout << "a-b=" << a - b << endl; //希望:-30

cout << "a/b=" << a / b << endl; //希望:-2

cout << "-a-b=" << -a - b << endl; //希望:10

cout << "-b+a=" << -b + a << endl; //希望:-30

//對結果進行強轉

cout << "a+b=" << (int)(a + b) << endl;

cout << "a*b=" << (int)(a * b) << endl;

cout << "a-b=" << (int)(a - b) << endl;

cout << "a/b=" << (int)(a / b) << endl;

cout << "-a-b=" << (int)(-a - b) << endl;

cout << "-b+a=" << (int)(-b + a) << endl;

實際情況呢?

a+b是個無符號的結果,通過強轉之後,是-10,可以負負得正,一般可控範圍

a*b是個無符號的結果,通過強轉之後,是-200,可以負負得正,一般可控範圍

a-b是個無符號的結果,通過強轉之後,是-30,可以負負得正,一般可控範圍

a/b是個無符號的結果,通過強轉之後,是429496727,不可以負負得正,屬於不可控範圍。

那麼為什麼只有除法不行了呢?

這個還是得從原理講起,首先,乘法 跟 除法 都是通過移位來解決的

乘法是 左移

除法是 右移

然後,再看下,負數表達形式(以32位系統為例)。

-32 如果是無符號的話,是這樣的:

如果是64bit,那麼前面再多8個f

運算乘法 與 除法 之前,都先轉 成 無符號的。

乘法,左移,之後,最高位仍然為1,當然前提資料不能溢位的情況,此時如果對結果再進行強轉回來,至少符號位還是正常的

除法,右移,之後,最高位補0,那麼就丟失了符號位,哪怕對結果再進行強轉回來,也是由於缺少符號位,導致最後資料仍然不對!

int a = -32;

unsigned int b = 16;

//此時會輸出什麼

a += b;

cout << "a += b a=" << a << endl;

//此時會輸出什麼

a /= b;

cout << "a /= b a=" << a << endl;

實際結果:

解釋:a是有符號,b是無符號,先a要轉換成無符號,然後再跟b計算,最後由於a是有符號的,結果又轉換成有符號,結果符合預期

第二種情況:也是這個步驟,只不過除法用移位方式實現,一旦最高位移掉之後,就不是想要的資料

-a - b,是個另類,-a的優先順序,要高於 「減法」 運算子,因此,要先處理 -a 而不是先轉成 無符號

那也說得通:-a = 20, 無符號之後,仍然 20  ;20 - 10 = 10 ,沒毛病

最後結論:

1. 如果沒有除法的話,無符號跟有符號運算,可以僅對結果進行強轉。(前提結果不能溢位)(不推薦這樣做,推薦第2種做法)

2. 如果有除法,必須先給無符號轉換成有符號的,再計算。

補充下,實際**的一些風險點:

這個是沒有問題的,但風格不好

有符號與無符號

最高位為1,表示這個數為負數 最高位為0,表示這個數為正數 include int main 執行結果 正數的補碼為正數本身 負數的補碼為負數的絕對值各位取反後加1 8位整數5的補碼為 0000 0101 8位整數 7的補碼為 1111 1001 16位整數20的補碼為 0000 0000 0001...

無符號與有符號

一,小精度往大精度轉換。1.1c語言中比int小的整型 包括short unsigned short unsigned char和char 在運算中都要轉換成int然後進行運算 unsigned char a unsigned char b a b 10,a和b分別先轉換成int,再計算 1.2同精...

有符號數與無符號數運算

有符號數與無符號數之間運算問題,這個問題測試是否懂得c語言中的整數自動轉換原則,有些開發者懂得極少這些東西。當表示式中存在有符號型別和無符號型別時所有的運算元都自動轉換為無符號型別。因此,從這個意義上講,無符號數的運算優先順序要高於有符號數,這一點對於應當頻繁用到無符號資料型別的嵌入式系統來說是丰常...