c++ 的除法的其余部分出现"堆栈溢出"异常

Remainder of a division with c++ getting 'Stack Overflow' exception

本文关键字:堆栈 异常 栈溢出 除法 余部 c++      更新时间:2023-10-16

我试图理解C++中的一些概念,我编写了这段代码来获取除法的其余部分(如%运算符):

double resto(double a, double b) {
if (a == b) return 0;
else if (a < b) return a;
else {
return resto(a-b, b);
}
}

当我使用(12,3)或(2,3)等较小的数字运行时,它运行良好。 但是如果我尝试使用参数(2147483647 * 1024,3)运行它,我会得到:

Stack overflow (parameters: 0x0000000000000001, 0x000000F404403F20)

由于我是C++新手,我不确定它是Visual Studio 2017的东西,还是编译器,还是堆栈内存等。

resto(2147483647 * 1024, 3); 

将递归2147483647 * 1024/3,或约7330亿次。每个递归调用都使用少量的自动存储来存储参数和簿记,并且程序可能会在达到一百万次迭代之前耗尽存储空间。

为此,您将不得不使用循环或更智能的逻辑(例如,减去较大的b倍数,直到使用较小的数字开始有意义),但fmod可能会更快、更有效。

其他注意事项:

2147483647 * 1024

是一个整数乘以一个整数。此数学运算将在int秒内进行,如果系统上的int位为 16 或 32 位,则溢出。当您溢出有符号整数时究竟会发生什么是不确定的,但通常该数字会进行 2s 补充环绕(假设为 32 位整数,则为 -1024)。有关溢出整数的更多详细信息,请参阅C++中是否有符号整数溢出的行为仍未定义?。用

2147483647.0 * 1024

以强制浮点数。

还要注意浮点数学坏了吗?浮点数是不精确的,通常很难获得应该相同但实际上相同的浮点数。 当你期望真实时,a == b通常是假的。此外,如果一个数字比另一个数字大得多a-b则可能没有明显的影响,因为ba结束时的噪音中丢失。两者之间的差异无法正确表示。