[英]How to cast or convert an unsigned int to int in C?
如果問題看起來很奇怪,我深表歉意。 我正在調試我的代碼,這似乎是問題所在,但我不確定。
謝謝!
這取決於您希望行為是什么。 int
不能包含unsigned int
可以保存的許多值。
你可以像往常一樣投射:
int signedInt = (int) myUnsigned;
但是如果unsigned
值超過int
可以容納的最大值,這將導致問題。 這意味着一半可能的unsigned
值將導致錯誤行為,除非您特別注意它。
如果您無緣無故地轉換,您可能應該首先重新檢查如何存儲值。
編輯:正如 ProdigySim 在評論中提到的,最大值取決於平台。 但是您可以使用INT_MAX
和UINT_MAX
訪問它。
對於通常的 4 字節類型:
4 bytes = (4*8) bits = 32 bits
如果使用所有 32 位,如unsigned
,最大值將為 2^32 - 1 或4,294,967,295
。
有符號int
實際上為符號犧牲了一位,因此最大值將為 2^31 - 1 或2,147,483,647
。 請注意,這是其他值的一半。
無符號整數可以通過簡單的表達式轉換為有符號(或反之亦然),如下所示:
unsigned int z;
int y=5;
z= (unsigned int)y;
雖然不是針對這個問題,但您想閱讀以下鏈接:
恕我直言,這個問題是常青樹。 如各種答案中所述,不在 [0,INT_MAX] 范圍內的無符號值的分配是實現定義的,甚至可能引發信號。 如果無符號值被認為是有符號數的二進制補碼表示,可能最便攜的方式是恕我直言,如下代碼片段所示:
#include <limits.h>
unsigned int u;
int i;
if (u <= (unsigned int)INT_MAX)
i = (int)u; /*(1)*/
else if (u >= (unsigned int)INT_MIN)
i = -(int)~u - 1; /*(2)*/
else
i = INT_MIN; /*(3)*/
分支 (1) 很明顯,不能調用溢出或陷阱,因為它是保值的。
分支(2)通過按位非取值的補碼,將其強制轉換為“int”(現在不能溢出),對值求反並減去一,這也可以避免有符號整數溢出。這里不會溢出。
分支(3)提供了我們必須對補碼或符號/大小目標采取的毒葯,因為有符號整數表示范圍小於二進制補碼表示范圍。
這很可能歸結為對二進制補碼目標的簡單移動; 至少我已經在 GCC 和 CLANG 中觀察到了這種情況。 同樣分支 (3) 在這樣的目標上是不可到達的——如果想將執行限制到二進制補碼目標,代碼可以壓縮為
#include <limits.h>
unsigned int u;
int i;
if (u <= (unsigned int)INT_MAX)
i = (int)u; /*(1)*/
else
i = -(int)~u - 1; /*(2)*/
該配方適用於任何有符號/無符號類型對,並且最好將代碼放入宏或內聯函數中,以便編譯器/優化器可以對其進行排序。 (在這種情況下,用三元運算符重寫配方是有幫助的。但它的可讀性較差,因此不是解釋策略的好方法。)
是的,一些對 'unsigned int' 的轉換是多余的,但是
他們可能會幫助普通讀者
一些編譯器在有符號/無符號比較時發出警告,因為隱式轉換會導致語言設計的一些非直觀行為
如果你有一個變量unsigned int x;
,您可以使用(int)x
將其轉換為int
。
就這么簡單:
unsigned int foo;
int bar = 10;
foo = (unsigned int)bar;
或相反亦然...
如果 unsigned int 和 (signed) int 在同一個表達式中使用,signed int 將隱式轉換為 unsigned。 這是 C 語言的一個相當危險的特性,因此您需要注意這一特性。 它可能是也可能不是您的錯誤的原因。 如果您想要更詳細的答案,則必須發布一些代碼。
一些解釋來自C++Primer 5th Page 35
如果我們將一個超出范圍的值分配給一個無符號類型的對象,結果是該值的余數以目標類型可以容納的值數為模。
例如,一個 8 位無符號字符可以保存從 0 到 255(包括 0 到 255)的值。 如果我們分配一個超出范圍的值,編譯器將分配該值的余數,取模 256。
unsigned char c = -1; // assuming 8-bit chars, c has value 255
如果我們將一個超出范圍的值分配給一個有符號類型的對象,結果是未定義的。 程序可能看起來工作正常,可能會崩潰,或者可能會產生垃圾值。
第 160 頁:如果任何操作數是無符號類型,則操作數轉換為的類型取決於機器上整數類型的相對大小。
... 當有符號數不同且無符號操作數的類型等於或大於有符號操作數時,將有符號操作數轉換為無符號操作數。
剩下的情況是有符號操作數的類型大於無符號操作數。 在這種情況下,結果取決於機器。 如果無符號類型中的所有值都適合大類型,則無符號操作數將轉換為有符號類型。 如果值不合適,則有符號操作數將轉換為無符號類型。
例如,如果操作數是 long 和 unsigned int,並且 int 和 long 的大小相同,則長度將轉換為 unsigned int。 如果 long 類型有更多位,那么 unsigned int 將被轉換為 long。
我發現閱讀這本書很有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.