Данный ряд Маклорена хорошо сходится при |x|<1, только при |x|≈1 надо брать большое число слагаемых. И чем ближе |x| к единице, тем большее количество слагаемых требуется учитывать, время при этом расходуется тоже всё больше и больше, а точность вычислений значительно снижается.
Вычисление суммы ряда можно организовать по разному. Например так, как в предыдущем ответе, то есть глупо и нерационально. Воспользовавшись модулем <chrono>, модифицируем основную функцию из предыдущего ответа следующим образом:
int main() { for (;;) {
const auto x = argument("x: ");
const auto ctrl = control(x);
auto start = chrono::system_clock::now();
cout.setf(ios::fixed);
cout.precision(15);
cout << "result: " << arthx(x) << '\n';
cout << "control: " << control(x) << '\n';
auto end = chrono::system_clock::now();
chrono::duration elapsed_seconds = end - start;
cout << elapsed_seconds.count() << " seconds" << endl; }
}
Запускаем код и начинаем вычислять:

При |х|=0,9999 сумма ряда у меня на смартфоне вычисляется почти минуту, а при |х|=0,99999 - порядка часа, что, конечно же, совершенно неприемлемо, но такова плата за глупость! В остальном же код вполне работоспособный.
Теперь рационализуем вычисления. У первого члена ряда в числителе х, а в знаменателе 1, у каждого последующего члена ряда числитель больше в х² раз, а знаменатель на 2 больше чем у предыдущего. Вот этим и воспользуемся:
#include
#include
#include
using namespace std;
int main()
{
double e, p, s, q, x, xx, y, Y;
while (true)
{
cout << "x » "; cin >> x;
cout.precision(16);
auto start = chrono::system_clock::now();
xx = x * x; e = p = q = y = 1.;
while (e > 1e-17)
{ q += 2.; p *= xx; e = p / q; y += e; }
y *= x;
auto end = chrono::system_clock::now();
chrono::duration elapsed_seconds = end - start;
Y = 0.5 * log((1. + x) / (1. - x));
cout << y << '\n' << Y << "\nAbsolute error: "
<< y - Y << "\nRelative error: " << y / Y - 1. <<
"\nNumber of terms taken in the series: " <<
(unsigned long long)((q - 1.) * 0.5) << endl;
cout.precision(8);
cout << elapsed_seconds.count() << " seconds" << endl;
}
}
