Задача
Сравнить скорость сходимости при вычислении числа [latex]e[/latex] с помощью ряда и бесконечной дроби:
[latex]e=2+\frac{1}{2!}+\frac{1}{3!}+\frac{1}{4!}+…[/latex]; [latex]e=1+\frac{1}{1-\frac{1}{2+\frac{1}{3-\frac{1}{2+\frac{1}{5-…}}}}}[/latex]
У нас дан ряд(row) и бесконечная дробь(inf). Для разложения числа [latex]e[/latex] в ряд использована функция вычисления факториала. Задаем начальные переменные и вычисляем основание натурального логарифма. При достижении заданной точности [latex]E[/latex] цикл вычислений ряда прекращается, и начинается вычисление по методу цепной дроби с заданным в первой части программы количеством итераций (для корректного сравнения скорости сходимости, количество итераций должно быть одинаково).
Алгоритм вычисления представляет собой цикл, в который вложен еще один рекурсивный цикл. Первый цикл do подставляет во второй цикл количество итераций. Во втором цикле for происходит основное вычисление цепной дроби, посредством проверки четных и нечетных шагов. Проверка на четность происходит делением текущей по счету итерации на 2 с остатком. Если делится без остатка, то итерация четная, иначе- нечетная.
E |
Количество итераций ряда(row) i |
Количество итераций цепной дроби(inf)l | Комментарий |
0.00001 | 9 | 7 |
Бесконечная дробь быстрее сходится к числу е, чем ряд. Тест пройден. |
0.0000002 | 11 | 9 |
Бесконечная дробь быстрее сходится к числу е, чем ряд. Тест пройден. |
0.00078 | 7 | 6 |
Бесконечная дробь быстрее сходится к числу е, чем ряд. Тест пройден. |
0.0004 | 7 | 6 |
Бесконечная дробь быстрее сходится к числу е, чем ряд. Тест пройден. |
При схождении к числу [latex]e[/latex] с точностью [latex]E[/latex] цепная дробь будет делать это быстрее, чем ряд.
Ниже представлена сама программа(C++).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#include <iostream> #include <math.h> using namespace std; double fact(int i) { if(i == 0) { return 1; } if(i < 0) { return 0; } else return i * fact(i - 1); //функция для вычисления факториала } int main() { int i=0, k=1, l=1; double row=0, E; //начальные переменные scanf("%lf", &E); //ввод погрешности do { row+=1/fact(i); //вычисление ряда i++; } while(M_E-row>E); //условие, при котором цикл останавливается printf("row=%10.10lf, i=%d \n", row, i); double sum3=0, inf; //переменные для вычисления цепной дроби do { for (int k = l; k >= 1; k--) { if ((k % 2) == 0) { sum3 = 1 / (2 + sum3); } else { sum3 = 1 / (k - sum3); } } if (fabs(M_E - (sum3 + 1))<E) { break; } l++; } while (l < i + 10); inf=1+sum3; //в начале цепной дроби присутсвует единица, которая выбивается из цикла. printf("inf=%10.10lf, l=%d \n", inf, l); if(l<i) { printf("С заданной погрешностью E=%5.10lf, бесконечная дробь, с количеством итераций l=%d быстрее сходится к числу е, чем ряд, c количевством итераиций i=%d.\n", E, l, i); } else { printf("С заданной погрешностью E=%5.10lf, ряд, с количеством итераций i=%d быстрее сходится к числу е, чем бесконечная дробь, c количевством итераиций l=%d.\n", E, i, l); } return 0; } |
Код на Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import java.util.*; import java.lang.*; import java.io.*; class Brovko { public static double fact(int itser){ return itser < 2? 1 : itser * fact(itser - 1); } public static void main (String[] args) throws java.lang.Exception { int itser=0, itfrac=1; double series=0, epsilon; Scanner in = new Scanner(System.in); epsilon=in.nextDouble(); do{ series+=1/fact(itser); itser++; } while(Math.E-series>epsilon); System.out.format("series=%10.10f, itser=%d \n", series, itser); double sum3=0, fraction; do{ for (int k = itfrac; k >= 1; k--){ if ((k % 2) == 0){ sum3 = 1 / (2 + sum3); } else{ sum3 = 1 / (k - sum3); } } if (Math.abs(Math.E - (sum3 + 1))<epsilon){ break; } itfrac++; } while (itfrac < itser + 10); fraction=1+sum3; System.out.format("fraction=%10.10f, itfrac=%d \n", fraction, itfrac); if(itfrac<itser){ System.out.printf("С заданной погрешностью epsilon=%5.10f, бесконечная дробь, с количеством итераций itfrac=%d быстрее сходится к числу е, чем ряд, c количевством итераиций itser=%d.\n", epsilon, itfrac, itser); } else{ System.out.printf("С заданной погрешностью epsilon=%5.10f, ряд, с количеством итераций itser=%d быстрее сходится к числу е, чем бесконечная дробь, c количевством итераиций itfrac=%d.\n", epsilon, itser, itfrac); } } } |
Также вы можете воспользоватся ссылкой (C++)/ссылкой (Java), для ознакомления с программой.
Почти зачёл. Программа-то работает. Но накопилось много «мелочей»:
— Нет смысла печатать накопленные значения. И так ясно какими они будут. Нужно печатать количество итерация для ряда и для дроби, обеспечивающих требуемую точность.
— Вы использовали два различных стиля отступов в одной программе. Нужно определиться и пользоваться каким-то одним. Местами (стр. 15, 23) сдвиг вообще ненужен.
— Используйте константу M_E, которая задана в math.h и представляет число e с максимальной для double точностью.
— row это сумма ряда. Нужно в 22-й строке задать начальное значение не 0, а 2. Вместо этого Вы отнимаете «магическую» двойку при сравнении.
— Зачем «магические» числа в 21-й и 29-й строке?
Исправил.
Немного схитрили. Вместо 2 в сумме ряда учли факториалы 0 и 1. Думаю это допустимо.
Зачёл.
Только поставьте отступы строках 28 и 51 в один уровень с остальным текстом.
P.S. Мне не очень нравится как Вы написали функцию для факториала. Зачем нужно доопределять факториал для отрицательных чисел? Я бы ещё понял, если бы Вы написали
Повторю одно из замечаний к посту Байкова.
Очень неудачный выбор для названия переменной E! Особенно в Java. Оно начинает путаться с Math.E, так же не забывайте, что обычно названия переменных начинаются с маленьких букв. Да и не логичное название. Назовите ее eps, или epsilon, или accuracy .
Также у Вас нарушены отступы.
Ряд в математике не row, а series. inf наверное тоже не самое удачное имя. l и i также не самая лучшая пара имен, как понять какая переменная для чего?
Исправлено.
С отступами немного не понял, но попытался сделать «как надо».