математика — я пытаюсь вычислить определенное число с помощью C ++ для циклов, но продолжаю получать сообщение «Программа перестала работать» Сообщение об ошибке

Я пытаюсь запустить этот код в 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;
}

Всякий раз, когда я компилирую и запускаю код, я получаю сообщение об ошибке Windows, что программа перестала работать. Может ли кто-нибудь помочь мне?

С помощью этого кода я пытаюсь вычислить следующее суммирование:

∑ 1 / н!

п = 0

-1

Решение

(Нижний предел вашей суммы должен быть 1, а не 0, но давайте отложим это.)

Ваш алгоритм настолько нестабилен, что никакие исправления не приведут к его эффективной работе. Проще говоря, факториалы просто становятся слишком большими. Поведение при переполнении целочисленного типа со знаком, кроме signed char или же char не определено Кажется, что происходит то, что int по сути, принимает факториал по модулю большой степени 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);
}

Выход 2.71828182845905 2.71828182845905 получается, показывая, что это правильно, так как сумма этой серии является математической константой е.

Хотя это прекрасно с точки зрения численности — скрытые глубины включают в себя тот факт, что термины имеют одинаковую величину, а сходимость происходит очень быстро, и этот ответ, как мы надеемся, развенчивает распространенный миф о том, что арифметика с плавающей запятой по своей сути неточна, недостатком этого подхода является необходимость знать верхний предел заранее; то есть вы не можете остановиться, когда достигается определенная терпимость. По опыту знаю, что вам понадобится около 20 терминов.

7

Другие решения

Это происходит потому, что 1000! на самом деле огромное количество, которое намного больше, чем то, что int или даже long long мог справиться. Также важно, что именно происходит в реальной жизни, когда умножение переполняется. Короче говоря, очень скоро ваш num было бы точно 0 что может быть немного удивительным для вас (это должно произойти, когда n! делится на 2^32). А потом попытаться вычислить 1/(num) терпит неудачу с арифметической ошибкой (деление на 0).

Подсказка: на самом деле 1000! настолько велика, что ни один стандартный тип не может справиться с этим (и 1/1000! достаточно мал, чтобы быть за пределами точности любого стандартного типа). Если вы действительно хотите рассчитать сумму достаточно точно, вам придется использовать несколько нетривиальных приемов.

4

  1. число не должно начинаться с -1
  2. ‘num’ взорвется при умножении
  3. Поплавок получает вас только так далеко. двойной лучше.

Следите за обратным факториалом. В этом случае вы можете просто разделить предыдущее значение.

#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;
}

дает:
2,71828

2
По вопросам рекламы [email protected]