@Lexluter20

В чём ошибка вычисления бесконечно убывающей прогрессии с точностью до эпсилон?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    double analit = 1.0, eps = 0.00000001, prog = 0.0;
    for(int i = 1; ; i++){
        prog += (double)1/(i*(i+1));
        if((analit - prog) <= eps){
            printf("%.10f\n%.10f\n%.10f\n%d\n", analit, prog, eps, i);
            return 0;
        }
    }

}

651c6c1fe5225895703206.png
Нужно найти сумму бесконечно убывающей прогрессии с точностью до eps, не пойму в чём ошибка и почему prog > 1 и prog > analit - eps?
код выводит:
1.0000000000
1.0796516589
0.0000000100
6697830
А должен по идеи
1.0000000000
0.9999999999
0.0000000100
какое-то количество итераций
  • Вопрос задан
  • 205 просмотров
Пригласить эксперта
Ответы на вопрос 3
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Целочисленное переполнение при умножении i на i+1. Замените на, скажем prog += 1/((double)i*(i+1));, должно сработать.

При i порядка 50000 результат перемножения не влезает в int. А у вас там 6697830 операций. В результате используются отрицательные или слишком маленькие неправильные значения i для вычисления слагаемых после 50000, и результат вообще не правильный.

Ну и, кстати, логика решения у вас неправильная. Надо не с конечным значением сравнивать, а останавливаться, когда следующее слагаемое становится слишком маленьким.
Ответ написан
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
У вас изначально неверная логика. Ваша программа не должна знать конечный результат вычислений. Она должна останавливаться, когда очередной вычисленный член ряда будет по модулю меньше заданной точности.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
У вас две ошибки.
1. Целочисленное переполнение в знаменателе в prog += (double)1/(i*(i+1));. Вычисляйте знаменатель в double, его длины более чем хватит.
2. Нельзя брать в счёт аналитический результат, надо высчитывать погрешность по имеющимся данным. Поскольку ещё и ряд сходится ХУдожественно — придётся помучиться, 1/(i(i+1)) < k·eps не катит (катит, если элемент ряда убывает экспоненциально, а у нас всего лишь квадратично).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы