C++ 我试图用C++;对于循环,但我一直得到;“程序已停止工作”;错误消息

C++ 我试图用C++;对于循环,但我一直得到;“程序已停止工作”;错误消息,c++,math,eulers-number,C++,Math,Eulers Number,我试图在Dev C++中运行此代码: #include<conio.h> #include<iostream> using namespace std; int main() { float sum =1; int num = -1; for(int i=1; i<=1000; i++) { num *= i;

我试图在Dev C++中运行此代码:

    #include<conio.h>
    #include<iostream>


    using namespace std;

    int main()
    {
        float sum =1;
        int num = -1;

        for(int i=1; i<=1000; i++)
        {
            num *= i;
            sum += 1/(num);
        }
        cout<<sum<<endl;
        getch();
        return 0;
    }
#包括
#包括
使用名称空间std;
int main()
{
浮动总和=1;
int num=-1;

对于(int i=1;i之所以发生这种情况,是因为
1000!
实际上是一个巨大的数字,比
int
甚至
long
所能处理的要大得多。另外,当乘法溢出时,在现实生活中到底发生了什么也是很重要的。长话短说,很快你的
num
将恰好是
0
这可能会让您有点惊讶(当
n!
可被
2^32
整除时会发生这种情况)。然后尝试计算
1/(num)
失败,并出现算术错误(被0整除)

提示:实际上,
1000!
太大了,没有标准类型可以处理它(而且
1/1000!
太小了,超出了任何标准类型的精度)。如果你真的想足够精确地计算总和,你必须使用一些非平凡的技巧。

(你的总和的下限应该是1而不是0,但我们把它放在一边。)

您的算法在数值上非常不稳定,没有任何修复将使其有效工作。简单地说,阶乘变得太大。溢出除
signed char
char
之外的有符号整数类型的行为是未定义的。似乎正在发生的是
int
基本上是采用阶乘模式lo一个2的大幂,最终它将是0,因为大阶乘是2的大幂的倍数。所以被0除会产生你观察到的行为

幸运的是,您可能会注意到您的总和可以写为

1 + 1/2(1 + 1/3(1 + 1/4...))
这在数值上要简单得多。一种方法是

#include <iostream>
#include <iomanip>
#include <cmath>
int main() {
    constexpr int N = 19;
    double sum = 1 + 1.0 / N;
    for (int n = N - 1; n >= 1; --n){
        sum = 1 + sum / n;
    }
    std::cout << std::setprecision(15) << sum << " " << std::exp(1);
}
#包括
#包括
#包括
int main(){
constexpr int N=19;
双和=1+1.0/N;
对于(int n=n-1;n>=1;--n){
sum=1+sum/n;
}
标准::cout
  • num不应以-1开头
  • “num”将在乘法时爆炸
  • 浮球只能让你走这么远,双倍更好
  • 跟踪逆阶乘。在这种情况下,您可以将前一个值除以

    #include<iostream>
    
    using namespace std;
    
    int main()
    {
        double sum = 1.0;
        int num = 1;
        double inv_fact = 1.0;
    
        for(int i=1; i<=1000; i++)
        {
          inv_fact = inv_fact / i;
          sum += inv_fact;
        }
        cout<<sum<<endl;
        return 0;
    }
    
    #包括
    使用名称空间std;
    int main()
    {
    双和=1.0;
    int num=1;
    双库存事实=1.0;
    
    对于(int i=1;i当您得到“程序已停止运行”时,是时候使用调试器运行您的程序了。添加一个结论,将这一非常好的数学探索与解释为什么该程序实际显示被问及的问题联系起来,以供投票!@LightnessRacesinOrbit:Dunnit.Delicious now:)有没有办法让它显示更多的数字?我上面的代码是:“cout.precision(15);coutHa.touch.Have up vote。现在我整个下午都在分心分析……你没有,这很了不起,因为我一直在搜索你的答案;-)