簡體   English   中英

如何在 C 中將無符號 int 轉換或轉換為 int?

[英]How to cast or convert an unsigned int to int in C?

如果問題看起來很奇怪,我深表歉意。 我正在調試我的代碼,這似乎是問題所在,但我不確定。

謝謝!

這取決於您希望行為是什么。 int不能包含unsigned int可以保存的許多值。

你可以像往常一樣投射:

int signedInt = (int) myUnsigned;

但是如果unsigned值超過int可以容納的最大值,這將導致問題。 這意味着一半可能的unsigned值將導致錯誤行為,除非您特別注意它。

如果您無緣無故地轉換,您可能應該首先重新檢查如何存儲值。

編輯:正如 ProdigySim 在評論中提到的,最大值取決於平台。 但是您可以使用INT_MAXUINT_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM