从int向unsigned int的转换

63

我很惊讶地发现,通过强制转换无法将带符号的整数转换为无符号整数!

int i = -62;
unsigned int j = (unsigned int)i;

我以为我已经知道了这一点,因为我开始使用类型转换了,但我做不到!


14
你期望这个演员阵容会做什么? - tenfour
抱歉,大家。但是我很感谢解释。我试图将有符号的char类型-62转换为无符号的int类型,并期望得到一个值为194 (x.x)。 - John
4
嗯...强制类型转换?在C++中,整数类型之间的转换不需要进行强制类型转换。它们是标准转换,并且会被隐式地执行。对于您的情况,您可以简单地使用unsigned int j = i;来达到完全相同的效果。 - AnT stands with Russia
5
您的代码编译得很好(在godbolt上查看)。您能否编辑问题,使其不再含义是不能编译?这会产生误导。 - Dr. Gut
1
有一点小问题,但对于新手来说,在C++中你不应该再使用c强制转换(unsigned int)i。应该使用static_cast<unsigned int>(i)。请参见https://dev59.com/n3VD5IYBdhLWcg3wDXJ3#103868以了解详细信息。 - Holger Böhnke
7个回答

65

你可以将int转换为unsigned int。这种转换是有效的和明确定义的。

由于值是负数,因此会向其添加UINT_MAX + 1,使该值成为有效的无符号数量(在技术上,将2N添加到其中,其中N是用于表示无符号类型的位数)。

在这种情况下,由于您的平台上int的宽度为32位,所以62被从232中减去,得到4,294,967,234。


6
@SIFE 所要转换的整数是-62... 当您将UINT_MAX(即2的32次方)加入其中时,它就会变成一个减去62的运算。 - Luke

49
编辑:正如其他答案中指出的那样,标准实际上保证“结果值是与源整数同余的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)”。因此,即使您的平台不将有符号整数存储为二进制补码,行为也将是相同的。


显然,您的有符号整数-62在您的平台上以二进制补码形式存储(维基百科):

32位二进制整数62的表示形式为:

0000 0000 0000 0000 0000 0000 0011 1110

为了计算二进制补码(以存储-62),首先需要翻转所有比特位。

1111 1111 1111 1111 1111 1111 1100 0001

然后加一

1111 1111 1111 1111 1111 1111 1100 0010

如果你把这个数解释为一个无符号32位整数(当你进行强制转换时,你的计算机会这样做),你最终将得到4294967234 :-)


9
这种转换是明确定义的,将产生值UINT_MAX - 61。在一个unsigned int为32位类型的平台上(现今大多数常见平台),这恰好是其他人报告的值。然而,可能会出现其他值。
标准中实际的语言是:

如果目标类型是无符号的, 则结果值是源整数对2^n取模后最小的 无符号整数。


1
由于标准已经有了明确的定义,为什么其他值仍然是可能的呢? - John
不同大小的整数具有不同的值。这就是为什么标准会谈到“同余”和“位数”的原因。 - soulsource

5

i=-62 . 如果你想将它转换成无符号表示法,那么对于32位整数,它将是4294967234。一个简单的方法是

num=-62
unsigned int n;
n = num
cout<<n;

4294967234


4

既然我们知道i是一个int,你可以直接对其进行无符号操作!

这样就可以解决问题了:

int i = -62;
unsigned int j = unsigned(i);

3

借助一些数学知识

#include <math.h>
int main(){
  int a = -1;
  unsigned int b;
  b = abs(a);
}

1
@chad:在C和C++中,signed -> unsigned转换的规范完全相同。它们在两种语言中的工作方式是一样的。 - AnT stands with Russia
2
哦天哪,我不小心刚刚删除了我的评论。非常抱歉!它原本的意思是这个不起作用,因为二进制补码表示法的差异。当我写这个时,我不知道自己在想什么,你是绝对正确的。 - chad

3

从c++17起,可以使用make_unsigned_t

auto uint_variable = std::make_unsigned_t<int>(-62); //4294967234

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接