![](/img/trans.png)
[英]What happens when I subtract an unsigned integer from a signed integer in C++?
[英]what happens when i mix signed and unsigned types ?
我正在学习C ++语言,我对类型转换有一些疑问,你能解释一下像这样的表达式会发生什么:
unsigned int u = 10;
int a = -42;
std::cout << u - a << std::endl;
在这里我知道如果我在有两个数学运算符时应用规则,结果将是52.但我想知道当编译器将a转换为无符号值时会发生什么情况会产生一个临时的无符号类型,之后会发生什么? 表达式现在应该是10 -4294967254。
简单来说,如果混合相同等级的类型(在int
, long int
, long long int
的序列中),则无符号类型“wins”,并且在该无符号类型内执行计算。 结果是相同的无符号类型。
如果您混合不同等级的类型,则排名较高的类型“获胜”,如果它可以表示较低等级类型的所有值。 计算在该类型内执行。 结果是那种类型。
最后,如果排名较高的类型不能表示较低排名类型的所有值,则使用较高排序类型的无符号版本。 结果是那种类型。
在您的情况下,您混合了相同等级的类型( int
和unsigned int
),这意味着整个表达式在unsigned int
类型中求值。 正如你所说的那样,表达式现在是10 - 4294967254
(对于32位int
)。 无符号类型遵循模运算规则,以2^32
( 4294967296
)作为模数。 如果仔细计算结果(可以算术地表示为10 - 4294967254 + 4294967296
),它将变为预期的52
。
1)由于标准的促销规则, signed
类型a
在减法之前被提升为unsigned
类型。 根据此规则(C ++标准4.7 / 2)进行促销:
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。
代数上a
变成一个非常大的正数,肯定比u
。
2) u - a
是匿名临时的,将是无符号类型。 (您可以通过编写auto t = u - a
并在调试器中检查t
的类型来验证这一点。)数学上这将是一个负数,但在隐式转换为无符号类型时,将调用类似于上面的环绕规则。
简而言之,两个转换操作具有相同和相反的效果,结果将是52.实际上,编译器可能会优化所有这些转换。
这里是反汇编代码说:
它首先将-42
设置为其补码并执行子操作。 所以结果是10 + 42
0x0000000000400835 <+8>: movl $0xa,-0xc(%rbp) 0x000000000040083c <+15>: movl $0xffffffd6,-0x8(%rbp) 0x0000000000400843 <+22>: mov -0x8(%rbp),%eax 0x0000000000400846 <+25>: mov -0xc(%rbp),%edx 0x0000000000400849 <+28>: sub %eax,%edx 0x000000000040084b <+30>: mov %edx,%eax
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.