c++除法的余数得到'Stack Overflow'异常

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

我试图理解 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 在您的系统上是 16 位或 32 位,则此数学运算将在 int 秒内发生并溢出。当你溢出一个有符号整数时,究竟会发生什么undefined, but typically the number does a 2s compliment wrap-around (to -1024 assuming 32 bit integer). More details on overflowing integers in Is signed integer overflow still undefined behavior in C++?。使用

2147483647.0 * 1024

强制浮点数。

还要注意 Is floating point math broken? 浮点数是不精确的,通常很难得到应该相同的浮点数实际上是相同的。 a == b 当您期望为真时,通常是假的。此外,如果一个数字比另一个数字大太多,a-b 可能没有明显的效果,因为 ba 末尾的噪音中丢失了。两者的区别无法正确表示。