C++整数溢出与下溢及int、short型乘法异常结果问询
C++代码异常运算结果成因解释
前提说明
以下结论基于主流32位/64位系统的标准实现:
- 32位有符号
int的取值范围是 [-2^31, 2^31 - 1],也就是 [-2147483648, 2147483647],采用补码存储 - 16位有符号
short的取值范围是 [-2^15, 2^15 - 1],也就是 [-32768, 32767]
场景1:int相乘输出异常结果的原因
C++标准规定有符号整数溢出属于未定义行为,但主流编译器均遵循补码截断规则:溢出后只保留计算结果的低32位,最终输出低32位对应的有符号整数值。
代码中a*a输出1的原因
a的值为2147483647,也就是2^31 - 1,乘积计算如下:a*a = (2^31 -1)^2 = 2^62 - 2^32 + 1
其中262和232的低32位全为0,截断后仅剩下1,因此最终输出结果为1。
代码中b*b输出0的原因
b的值为-2147483648,也就是-2^31,乘积计算如下:
b*b = (-2^31)^2 = 2^62
2^62的低32位全为0,截断后结果为0,因此最终输出结果为0。
场景2:short相乘结果为int类型的原因
这是C++的整型提升规则要求:所有取值范围小于int的整型类型(包括short、char、bool等)在参与算术运算前,会先被隐式转换为int类型再执行计算。
代码中x*x输出1073676289的原因
x的值为32767,转换为int后值不变,乘积32767 * 32767 = 1073676289,该值小于int的最大值2147483647,没有发生溢出,因此直接输出正确计算结果。
代码中y*y输出1073741824的原因
y的值为-32768,转换为int后值不变,乘积(-32768) * (-32768) = 1073741824,同样没有超出int的取值范围,因此直接输出正确计算结果。
内容的提问来源于stack exchange,提问作者Rivu Adhikary
相关产品推荐
相关产品推荐

