C++;限值和负值的整数除法运算? 我在C++中遇到了整数除法的奇怪结果。我正在计算:-2147483648/-1

C++;限值和负值的整数除法运算? 我在C++中遇到了整数除法的奇怪结果。我正在计算:-2147483648/-1,c++,integer,precision,16-bit,integer-division,C++,Integer,Precision,16 Bit,Integer Division,我得到的是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 &l

我得到的是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;
}
intfoo(int分子,int分母){
int res=分子/分母;//产生SIGFPE,算术异常中断

cout您的结果可能是
INT\u MAX+1
,换句话说,它可能会溢出。这是未定义的行为,任何事情都可能发生。例如,编译器可能会完全拒绝代码


(一个系统可能有
INT\u MAX>=2147483648
,但是你会期望对你的3个测试用例得到相同的结果)

你的编译器将文本
-2147483648/-1
计算为
2147483648
,数据类型的宽度足以容纳该值

直接打印文本时,它会正确打印值

当文本存储在
res
中时,它被强制转换为
int
int
在您的系统上显示为32位宽。值
2147483648
不能表示为32位有符号整数,因此强制转换会导致溢出。在您的系统上,此溢出会导致值
-2147483648
(很可能是使用了二的补码)

最后,当尝试在运行时执行除法时(在
foo
函数中),由于溢出而发生
SIGFPE
异常(因为
int
数据类型无法表示结果)

请注意,这三个选项都依赖于平台相关的行为:

  • 事实上,当文本计算溢出时,编译器不会生成任何错误(或其他问题),只使用足够大的数据类型来保存结果
  • 存储文本时,
    int
    溢出会生成该特定值(没有其他问题)
  • SIGFPE
    异常在运行时溢出时抛出的事实
int res=-2147483648/-1;

值得一提的是,Windows VS-2015上的代码没有编译,它说
负整数常量转换为无符号类型
应用于无符号类型的一元减号运算符,所有
-2147483648/-1
行简单答案的结果仍然是无符号的。visual studio就是这样做的:
\define INT\u MIN(-2147483647-1)//最小(有符号)int值
@usr
2147483648
甚至在考虑一元
-
之前都是UB。因此VC define通过避免
2147483648
文字来解决这个问题。@flatmouse:我猜他们错误地使用了适用于整体升级的列表,即int、unsigned int、long int、unsigned long int、long long int或unsigned long long int"或者他们使用用于二进制/八进制/十六进制文本的列表,而不是用于十进制文本的列表。至于为什么二进制/八进制/十六进制文本的规则不同,我相信这是因为程序员然后控制文本的长度,以位为单位。实际上,我希望看到
auto x=0x0000000000000001;
automat无论基本类型满足
int64\u least\t
ideaAFAICT整数溢出,编译期间的溢出都是未定义的行为;使用更大的数据类型是一种可能的行为,但正如第一步所示,另一种行为是出错。@MSalters:是的,我在最后一段中也说明了这一点。这也是一个错误:每个平台都有o支持足够宽的数据类型;
long int
当然足够宽了。@MSalters:你说得对-根据C++03,我习惯于回答标有“C++”的问题,但因为C++11(和C++14)已经有一段时间了出来后,我应该顺应时代,调整这个习惯。我已经重新措辞了我的回答的一部分。<代码> -2147483648 可以是<代码>长long < />代码,例如在MSVC(它有<代码> LangyMax=2147483647 < /Cord>)Irc在旧版本的C++中,它也可以是32位无符号长。(这实际上并没有改变最终结果,但它确实改变了你的结果)。C++ PuffCH我不太了解“老”C++。,它不会是无符号的,除非使用后缀
u
。表示是实现定义的,所以
long
可以用32位整数表示。@plugwash我发现,“在C99之前的C中(但不是在C++),不适合long int的无符号十进制值可以有无符号long int类型。”
int res = -2147483648 / -1;
cout << res << endl;               // prints -2147483648
cout << -2147483648 / -1 << endl;  // prints 2147483648
int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt