我在C ++中使用整数除法遇到一些奇怪的结果。我想计算一下: -2147483648 / -1 。
我得到的是3种不同场景中的3种不同结果:
int foo(int numerator, int denominator) {
int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt
cout << res << endl;
}
int main() {
int res = -2147483648 / -1;
cout << res << endl; // prints -2147483648
cout << -2147483648 / -1 << endl; // prints 2147483648
foo(-2147483648, -1);
return 0;
}
为什么整数除法运算在不同情况下会产生不同的结果?
答案 0 :(得分:12)
您的结果可能是INT_MAX+1
,换句话说,它可能会溢出。这是未定义的行为,任何事情都可能发生。例如,编译器可能会完全拒绝该代码。
(系统可能有INT_MAX >= 2147483648
,但是对于3个测试用例,你会得到相同的结果)
答案 1 :(得分:12)
文字-2147483648 / -1
由编译器计算为2147483648
,数据类型的宽度足以容纳该值。
直接打印文字时,它会正确打印值。
当文字存储在res
中时,它会转换为int
。您的系统上int
似乎是32位宽。值2147483648
不能表示为32位有符号整数,因此转换会导致溢出。在您的系统上,此溢出会产生值-2147483648
(可能是使用了两个补码)。
最后,当尝试在运行时(在foo
函数中)执行除法时,由于溢出而发生SIGFPE
异常(因为int
数据类型不能表示结果)
请注意,所有这三个选项都依赖于平台相关的行为:
int
溢出的事实会产生该特定值(并且没有其他问题)SIGFPE
异常的事实答案 2 :(得分:10)
int res = -2147483648 / -1;
cout << res << endl; // prints -2147483648
cout << -2147483648 / -1 << endl; // prints 2147483648
int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt
请注意,没有否定integer literals。
没有负整数文字。诸如-1之类的表达式将一元减号运算符应用于由文字表示的值,这可能涉及隐式类型转换。
文字2147483648
大于int
的最大值,因此其类型将为long
(或long long
,具体取决于实施情况)。然后,-2147483648
的类型为long
,计算结果(-2147483648 / -1
)也为long
。
对于第一种情况,类型2147483648
的结果long
为implicitly converted到int
,但它大于{{1}的最大值结果是实现定义的。 (似乎结果是根据表示的规则(2&#39;补码)包含在这里,所以你得到结果int
。)
对于第二种情况,类型-2147483648
的结果将直接打印出来,因此您可以得到正确的结果。
对于第三种情况,您要对两个long
进行计算,结果不适合结果类型(即int
),{{3发生了,行为是未定义的。 (在此处生成SIGFPE,算术异常中断。)