为什么有时我会溢出,有时不会在 C 中

eil*_*ano -2 c integer-overflow

我有这个代码,这两个计算给了我不同的结果。
第一个溢出,第二个只保留 2^31-1。

我不明白为什么。

int n4, n5;

n4 = pow(2, 31);
n4 = n4 + n4;
n5 = pow(2, 31) + pow(2, 31);

printf("\nn4: %d, n5: %d",n4,n5);
/* n4: -2, n5: 2147483647 */
Run Code Online (Sandbox Code Playgroud)

Erd*_*çük 6

的返回值pow的类型为double

所以,pow(2, 31) + pow(2, 31)在adouble可以表示的范围内。

赋值n5 = (double) ...将 转换doubleint。但是由于该值不能用 an 表示int,因此您会得到 (2^31)-1 作为结果。基本上,您将double值限制为int((2^31)-1)的最大值。

第一种情况是溢出,因为 的结果n4 + n4是 类型int。并且该值超过了最大值。

C 标准草案 N2176

6.3 转换
6.3.1.4 实数浮点数和整数

  1. 当实浮点类型的有限值转换为_Bool 以外的整数类型时,小数部分将被丢弃(即,该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为未定义。

是的,转换是UB。但是为了解释 OP 的结果,我“假设”该值已被限制在int.