Последовательность, которую вы хотите оценить, сходится к pi. Эта последовательность возникает, когда вы рассматриваете развитие Тейлора arctan
функции в x=1
, поэтому arctan(1)=pi/4
:
К сожалению, это расширение не сходится очень быстро (думаю, что все нечетные monoms равны 1, так что вы теряете их сила сходимости). Существуют лучшие способы оценки десятичных знаков pi.
В любом случае, как указано ранее, рекурсия не должна использоваться для решения этой проблемы. Фактически рекурсия должна использоваться только в нескольких случаях. Например: если вы можете доказать, что алгоритм разделения и завоевания уменьшает сложность задачи, которую вы хотите выполнить. В вашем случае это совсем не так, поэтому избегайте этого. Вы просто пополните - и, возможно, переполняете свой call stack
без необходимости. Как указывалось другими, ваша проблема может быть решена с помощью классического цикла.
Вы можете решить, как это:
#include <iostream>
#include <iomanip>
#include <cmath>
int main(void) {
double x0 = 0.0;
double x1 = 0.0;
double eps = 0.0001;
double s = 1.0;
int i = 0;
int maxiter = 100000;
do {
// Save Previous Term in order to compare with the next:
x0 = x1;
// Compute Next Term:
x1 += s*4.0/(2*static_cast<double>(i)+1);
// Change Sign:
s *= -1.0;
// Increase Counter:
i++;
// Log:
std::cout << std::setw(6) << i << std::fixed << "\t"
<< x1 << "\t" << std::setw(10) << (x1-x0) << std::endl;
// Loop until convergence criterion is met or max iteration is reached:
} while((std::abs(x1-x0)>eps)&&(i<maxiter));
return 0;
}
Если вы не знаете, сколько шагов потребуется, чтобы сходиться вам нужен loop
вместо for
заявления. В вашем случае loop
не требуется, так как вы можете записать разницу между двумя последовательными терминами и определить, сколько шагов требуется для этого достаточно малого по отношению к вашему критерию epsilon.
Во всяком случае, если вы используете цикл, вы должны убедиться, что:
- Loop будет когда-нибудь выйти на какой-то момент (во избежание бесконечного цикла);
- При выходе из строя результат верный.
Именно по этой причине я использую два критерия в моем состоянии цикла. Второе не нужно, так как я могу показать, что расстояние между двумя последовательными членами обращается в нуль до 0
, так как i
растет. Но я, возможно, захочу, чтобы цикл остановился, прежде чем я достиг некоторого порога итерации.
Вам не хватает набора брекетов (скобок) в предложении 'else '? – KeithSmith
'calc' всегда 4 при достижении' if (calc == 0.0001) ', поэтому он никогда не вызовет возврата – fredrik
Кроме того,' i' всегда '1', а также' f'. – Johnsyweb