Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Подсчет суммы членов ряда. С++

71K
07 июня 2011 года
AleksandrT
1 / / 07.06.2011
Здравствуйте, уважаемые!

Помогаю другу решить задачу по программированию. Передо мной стоит следующая задача:
Вычислить сумму членов ряда с точностью к члену ряда, меньшему eps. Вывести значение каждого члена ряда
[ATTACH=CONFIG]5182[/ATTACH]

Попробовал решить эту задачу. Получился такой код:
Код:
#include <conio.h>
#include <stdio.h>
#include <math.h>

double factorial (double f); //функция вычисления факториала. Double здесь используется в связи с тем, что в него влазит больше чем в int.

void main ()
{
    double x = 0;               //х
    double x_next = 0;      //Переменная для расчета очередного члена ряда.
    double sum = 0;         //Переменная для расчета общей суммы.
    double eps;                 //Точность
    int n = 1;                      //n
    int key;                            //Переменная используется для записи кода нажатой клавиши.
                                        //Используется только в одном месте.
                                        //Можно обойтись и без неё, но тогда интерфейс программы будет не красивый.
   
    clrscr();                       //Очистка экрана на тот случай если программа будет запускаться с коммандной строки.
    printf("Enter x. To solve this task it has to be between 0 and 1:");            //Ввод х
    scanf("%lf",&x);
    clrscr();
    printf("x = %lf",x);            //Я бы не советовал сюда вводить большие числа, т.к. в double получившееся число может не влезть.
    printf("\nEnter epsilon between 0 and 1:"); //Ввод точности
    scanf("%lf",&eps);
    if (eps <= 0 || eps >= 1)                           //Проверка ввода.
        do                                                          //Точность должна быть между 0 и 1.
        {                                                               //Если нет, тогда пользователя программа просит ввести её ещё раз или выйти из программы.
            printf ("\nYou've just entered a wrong value for epsilon.\nPress any key to continue  or ESC to exit.");
            key=getch ();                                       //Это реализовано в цикле do...while пока пользователь не введет
            if (key == 27)                                      //правильное значение или не нажмет клавишу ESC.
                return;                                         //Это выход из программы
            clrscr();
            printf("x = %lf",x);
            printf("\nEnter epsilon between 0 and 1:"); //Повторный запрос
            scanf("%2f",&eps);
        } while (eps <= 0 || eps >= 1);
    clrscr();                                           //Очистка экрана для красоты
    printf("x = %lf\teps = %lf",x,eps);     //Вывод всех переменных, которые ввёл пользователь
   
    printf ("\nMembers of series:\n");      //Выводится "Члены ряда" на английском. Не уверен, что я правильно перевёл.

    while (fabs(x_next = pow(-1, n + 1) * pow(x, 2 * n - 1) /( (2 * n - 1) * factorial(2 * n - 1))) > eps) //Если очередной член ряда меньше epsilon (точности) тогда заканчиваем расчёт. Сюда же забита функция расчета.
    {
        printf ("(%i): %f\n",n,x_next);     //Выводим кадый член ряда
        sum += x_next;
        n++;
    }
   
    printf("\n\nsum = %f", sum);                    //Выводим сумму
    printf("\n\nPress any key...");
    getch ();                                       //Задержка, чтобы пользователь смог увидеть результат. Чтобы закончить надо нажать любую клавишу.
}

double factorial (double f) //Функция для расчета факториала числа.
                                    //Обращаю внимание на то, что если даже в эту функцию
                                    //каким-то образом попадет не целое число, оно преобразуется в целое.
{
    double a = 1;
    double c = 1;
    if (f<=0)                   //Если число будет меньше или равно нулю, тогда факториал считаться
    {                               //не будет и будет чисто формально выводить -1. Это нужно проверять,
        return 1.0;         //но в моей программе это не нужно, т.к. пользователь не может туда
    }                               //ввести число, а программа заносит туда, если логически подумать,
                                    //только целые числа больше 1. Этот кусок кода можно убрать, т.к. это бесполезная проверка в нашем случае.
    while (a<=f)                //Организация расчета факториала числа.
    {
        c*=a;
        a++;
    }
    return c;                   //Возращаемое значение функции.
}


Программа почему-то "выкидывает" ошибку "Floating point overflow", если ввести, к примеру, x = 62, eps = 0,00001. Я так понял, что число, которое используется при вычислениях уже не "влазит" в переменную. Подскажите, пожалуйста, где я сделал ошибку и как мне её исправить, чтобы программа работала для всех значений?

Ошибка "выскакивает" внутри цикла
 
Код:
while (fabs(x_next = pow(-1, n + 1) * pow(x, 2 * n - 1) /( (2 * n - 1) * factorial(2 * n - 1))) > eps) //Если очередной член ряда меньше epsilon (точности) тогда заканчиваем расчёт. Сюда же забита функция расчета.
    {
        printf ("(%i): %f\n",n,x_next);     //Выводим кадый член ряда
        sum += x_next;
        n++;
    }


Спасибо!
87
07 июня 2011 года
Kogrom
2.7K / / 02.02.2008
Слишком большие pow(x, 2 * n - 1), factorial(2 * n - 1) - происходит переполнение.
Предлагается такое решение: не рассчитывать каждый раз x_next с нуля, а изменять предыдущее значение. Тут надо найти некий изменяющийся коэффициент.
87
07 июня 2011 года
Kogrom
2.7K / / 02.02.2008
Как-то так (стиль кода не менял):
Код:
void sum(double x, double eps)
{
    double x_next = x;        
    double sum = 0;            
    int n = 1;                        


    printf("\n\n\nx = %lf\teps = %lf",x,eps);      

    printf ("\nMembers of series:\n");        

    while (fabs(x_next) > eps)
    {
        printf ("(%i): %lf\n",n,x_next);        
        sum += x_next;
        n++;
        x_next = -1 * x_next * pow(x, 2)*(2 * n - 3) /( (2 * n - 1) * (2*n - 1) * (2*n - 2));
    }

    printf("\n\nsum = %lf", sum);                  

}

int main ()
{

    sum(5, 1);
    sum(62, 0.00001);

    return 0;
}

Проверяйте со своими данными.
Факториал тут не нужен.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог