double k = 0;
int l = 1;
double digits = pow(0.1, 5);
do
{
k += (pow(-1, l - 1)/l);
l++;
} while((log(2)-k)>=digits);
我正在尝试根据我看到的使用一系列Σ_(l = 1)(pow(-1,l - 1)/ l)来估算log(2)的例子来编写一个小程序;
它应该是一个猜测细化的东西,它越来越接近正确的值,直到这么多的数字匹配。
以上就是我尝试的但是它没有出来。在弄乱了很长一段时间后,我无法弄清楚我在哪里弄乱。
答案 0 :(得分:1)
我假设你试图通过泰勒系列扩展来扩展2的自然对数:
∞ (-1)n + 1 ln(x) = ∑ ――――――――(x - 1)n n=1 n
您的代码的一个问题是选择以指定的精度停止迭代的条件:
do { ... } while((log(2)-k)>=digits);
除了直接使用log(2)
之外(你不应该找到它而不是使用库函数吗?),在第二次迭代(以及其他每次迭代)log(2) - k
得到负(-0.3068 ......)结束循环。
可能(但不是最佳)修复可能是使用std::abs(log(2) - k)
,或者当1.0 / l
的绝对值(这是两次连续迭代之间的差异)足够小时结束循环。
此外,使用pow(-1, l - 1)
来计算序列1,-1,1,-1,......实际上是一种浪费,特别是在收敛速度较慢的系列中。
更有效的系列(见here)是:
∞ 1 ln(x) = 2 ∑ ――――――― ((x - 1) / (x + 1))2n + 1 n=0 2n + 1
您可以在不使用pow
的情况下进行评估:
double x = 2.0; // I want to calculate ln(2)
int n = 1;
double eps = 0.00001,
kpow = (x - 1.0) / (x + 1.0),
kpow2 = kpow * kpow,
dk,
k = 2 * kpow;
do {
n += 2;
kpow *= kpow2;
dk = 2 * kpow / n;
k += dk;
} while ( std::abs(dk) >= eps );