基本原則:
1、一般singed 型資料和unsigned型資料進行四則運算,是要轉換成unsigned的,
2、兩種資料型別相乘,會將其轉換成範圍更廣的資料型別,再作運算。如unsigned short 與int相乘,會被轉成int再作相乘,其最終結果也被認為是有符號的
例:1)
unsigned short a;
int b;
a*b 將會被認為是乙個有符號型 ( int 型的表示範圍比unsigned short型表示範圍更寬 )
2)
unsigned int a;
int b;
a*b 將會被認為是乙個無符號型 ( unsigned int型的表示範圍比 int型表示範圍更寬 )
3)運算元混合了有符號數,無符號數
inta = -1;
unsigned int b = 2;
b/a;
對於該情形,
因為涉及到不同符號數的混合計算,在計算之前需要先對運算元進行規整化的動
作,規整的原則就是如果運算元中存在至少乙個無符號數(前提要求兩個運算元據位長是一致的,該例中都是32位),
則所有運算元都被轉化為無符號數,
運算操作也採用相應的無符號操作符進行,計算完的結果也是乙個無符號數。
舉例來說:
(unsigned int)b / (signed int)a
會採用無符號除法進行,其實質相當於
(unsigned int)b / (unsigned int)a
計算結果也是乙個無符號數,結果為(unsigned int)2 / (unsigned int)-1 = 0x2/0xffffffff = 0
再進一步,對於運算
-2 / -1
,如果採用有符號數運算,
結果是2
,採用無符號數運算,
結果則是0。
舉例
在工作中遇到乙個問題,
unsigned short a1 = 1920;
unsigned short a2 = 3840;
a1*2^20 計算得出為乙個正數
( a1為unsigned short型,2^20為int型,計算時會先轉換成int型再作運算,最終結果將是int型 )
1920 * 2^20 = 0x78000000 ( int 型0x78000000實際也是乙個正數 )
a2*2^20 計算得出為乙個負數
3840* 2^20 = 0xf0000000 = -268435456 ( int型0xf0000000實際是乙個負數 )
分析如下
2^20 * 1920 = 0x78000000
2^20 * 3840 = 0xf0000000
在計算機中,將0xf000000當作乙個負數作處理,其數值為-268435356 ( 具體轉化過程參考另一文件《
負數在計算機中如何表示?
》 )
如下所示code的結果為
-268435456
fffdddde 167d30
-139810 1473840
#include main()
我們在面試時經常給你乙個非常簡單的式子,比如unsigned int a,int b;請你分析a+b,a*b啥現象,不要輕心,這個東西返回的東西很奇怪的,或者問你(a+b) > 0是真是假,這樣我們就回到了開始提出的問題,由於是乙個負數乘了乙個dword,所以返回的是乙個無符號的(bc編譯器,可能他這兒是無符號的,看具體的編譯器),我們加乙個有符號的強制轉換後,發現正常,說明正好我們提出的猜想是完全正確的。
分類: c語言
有符號數與無符號數運算
有符號數與無符號數之間運算問題,這個問題測試是否懂得c語言中的整數自動轉換原則,有些開發者懂得極少這些東西。當表示式中存在有符號型別和無符號型別時所有的運算元都自動轉換為無符號型別。因此,從這個意義上講,無符號數的運算優先順序要高於有符號數,這一點對於應當頻繁用到無符號資料型別的嵌入式系統來說是丰常...
有符號數與無符號數
關於有符號數和無符號數的一些重要知識點,包括它們在記憶體中的儲存方式 互相轉換 越界計算等。大家肯定都知道,對於有符號數,資料型別的最高位用於標示資料的符號,最高位為1表示負數,最高位為0表示正數,那麼今天我們主要就此討論乙個問題 在計算機內部具體是如何表示有符號數呢?在計算機內部是通過補碼的方式來...
Verilog 有符號數與無符號數運算
無符號數運算,左值位寬不夠,發生截斷的現象 2.兩個無符號數運算,賦值給乙個有符號的數。可以看出,右側先按照無符號數進行運算,取得的運算結果按照左側的符號進行資料顯示。3.兩個無符號數運算,無符號數賦負值 補碼 按照該補碼對應的正值進行處理。結果同上。4.有符號數和無符號數運算,賦值給有符號數。補碼...