Leo*_*Lai 25 c++ unsigned arithmetic-expressions integer-overflow
以下结果让我很困惑:
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
Run Code Online (Sandbox Code Playgroud)
i3似乎计算为(20u-80u)/2,而不是(20-80u)/2i3是一样的i5.小智 13
IIRC,signed和unsigned int之间的算术运算将产生无符号结果.
因此,20 - 80u产生等效于的无符号结果-60:if unsigned int是32位类型,结果是4294967236.
顺便说一句,指定它以i1产生实现定义的结果,因为数字太大而不适合.获得-60是典型的,但不能保证.
aut*_*tic 10
Run Code Online (Sandbox Code Playgroud)int i1 = 20-80u; // -60
这有微妙的恶魔!操作数是不同的,因此转换是必要的.两个操作数都转换为通用类型(unsigned int在本例中为an ).结果将是一个较大的unsigned int值(比UINT_MAX + 1我的计算正确时少60 )将在int存储之前转换为i1.由于该值超出范围int,结果将是实现定义,可能是陷阱表示,因此当您尝试使用它时可能会导致未定义的行为.但是,在你的情况下它恰巧转换为-60.
Run Code Online (Sandbox Code Playgroud)int i3 =(20-80u)/2; // 2147483618
继续从第一个例子开始,我的猜测结果20-80u将是60比UINT_MAX + 1.如果UINT_MAX是4294967295(一个共同的价值UINT_MAX),这将意味着20-80u是4294967236......并4294967236 / 2为2147483618.
至于i2和其他人,应该没有意外.它们遵循传统的数学计算,没有转换,截断,溢出或其他实现定义的行为.