C++ 有符号和无符号之间的减法,然后是除法
以下结果让我非常困惑:C++ 有符号和无符号之间的减法,然后是除法,c++,unsigned,integer-overflow,arithmetic-expressions,C++,Unsigned,Integer Overflow,Arithmetic Expressions,以下结果让我非常困惑: int i1 = 20-80u; // -60 int i2 = 20-80; // -60 int i3 =(20-80u)/2; // 2147483618 int i4 =(20-80)/2; // -30 int i5 =i1/2; // -30 i3似乎被计算为(20u-80u)/2,而不是(20-80u)/2 假定i3与i5相同 IIRC,有符号和无符号整数之间的算术运算将产生无符号结果 因此,20-80u产生的无符号结果相当于-
int i1 = 20-80u; // -60
int i2 = 20-80; // -60
int i3 =(20-80u)/2; // 2147483618
int i4 =(20-80)/2; // -30
int i5 =i1/2; // -30
i3
似乎被计算为(20u-80u)/2
,而不是(20-80u)/2
i3
与i5
相同IIRC,有符号和无符号整数之间的算术运算将产生无符号结果 因此,
20-80u
产生的无符号结果相当于-60
:如果无符号int
是32位类型,则该结果为4294967236
顺便说一句,将其分配给i1
会产生一个实现定义的结果,因为该数字太大,无法容纳。获得-60
是典型的,但不能保证
这里有微妙的恶魔操作数不同,因此需要进行转换。两个操作数都转换为公共类型(在本例中为无符号int
)。结果将是一个大的无符号int
值(如果我的计算正确,则小于UINT_MAX+1
60),在存储到i1
之前,它将被转换为int
。由于该值超出了int
的范围,因此结果将由实现定义,可能是陷阱表示,因此在尝试使用它时可能会导致未定义的行为。但是,在您的情况下,它会同时转换为-60
从第一个示例继续,我猜测
20-80u
的结果将比UINT_MAX+1
小60。如果UINT_MAX
是4294967295(一个UINT_MAX
的公共值),这意味着20-80u
是4294967236
。。。而4294967236/2
是2147483618
至于
i2
和其他,应该不会有什么意外。它们遵循传统的数学计算,没有任何转换、截断、溢出或其他实现定义的行为。二进制算术运算符将对其操作数执行操作,以将其转换为通用类型
在i1
、i3
和i5
的情况下,常见类型将是无符号int,因此结果也将是无符号int。无符号数字将通过模运算进行换行,因此减去稍大的无符号值将导致接近无符号int max的数字,而该数字不能用int表示
因此,在i1
的情况下,由于无法表示值,因此我们最终会进行实现定义的转换。在i3
除以2
的情况下,无符号值会回到int的范围内,因此我们在转换后得到一个大的有符号int值
<> >相关章节构成C++草稿标准如下。第5.7节5.7
[expr.add]:
加法运算符+和-从左向右分组。通常的算术转换是针对
算术或枚举类型的操作数
第5节介绍了常用的算术转换,其中说明:
许多需要算术或枚举类型操作数的二进制运算符会导致转换并产生
结果类型以类似的方式显示。目的是生成一个公共类型,它也是结果的类型。
此模式称为常用算术转换,其定义如下:
[……]
- 否则,如果具有无符号整数类型的操作数的秩大于或等于 另一个操作数类型的秩,有符号整数类型的操作数应转换为 具有无符号整数类型的操作数的类型
4.7节[conv.integral]:
如果目标类型是有符号的,则如果可以在目标类型(和)中表示该值,则该值将保持不变
位域宽度);否则,该值由实现定义
对于无符号整数,遵循模算术部分3.9.1
[basic.basical]:
无符号整数应遵循算术模2n定律,其中n是值中的位数
表示整数的特定大小。48
顺便提一下,将该值指定给i1是未定义的行为,您确定吗?我教过,对于无符号int的所有值,从无符号int到有符号int的转换都有很好的定义。这里没有符号整数溢出。有转换。看。@rozina:嗯,我以前从来没有见过转换在这方面有不同的效果。如果我理解正确的话,将-1转换为unsigned是很好定义的,它是UINT_MAX。但是如果你将UINT_MAX转换回int,它会突然被实现定义吗?不可能是-1吗?回答得很好:)@Hurkyl:该死,我今天站着睡觉,我弄坏了未签名的溢出和从未签名到已签名的转换(后者由实现定义)。我会自毁我的评论。。。
int i1 = 20-80u; // -60
int i3 =(20-80u)/2; // 2147483618