如何在 C 中用连分数实现自然对数​​?

How to implement natural logarithm with continued fraction in C?

这里有个小问题。从这个公式创建一些东西:

我有这个,但是没用。弗兰基,我真的不明白它应该如何工作。我试着用一些错误的指令来编写它。 N 是迭代次数和分数部分。我认为它以某种方式导致递归但不知道如何。

感谢您的帮助。

double contFragLog(double z, int n)
{
    double cf = 2 * z;
    double a, b;
    for(int i = n; i >= 1; i--)
    {
        a = sq(i - 2) * sq(z);
        b = i + i - 2;
        cf = a / (b - cf);

    }
    return (1 + cf) / (1 - cf);
}

中央环路一团糟。返工。也不需要递归。只需先计算最深的项,然后再算出来。

double contFragLog(double z, int n) {
  double zz = z*z;
  double cf = 1.0;  // Important this is not 0
  for (int i = n; i >= 1; i--) {
    cf = (2*i -1) - i*i*zz/cf;
  }
  return 2*z/cf;
}

void testln(double z) {
  double y = log((1+z)/(1-z));
  double y2 = contFragLog(z, 8);
  printf("%e %e %e\n", z, y, y2);
}

int main() {
  testln(0.2);
  testln(0.5);
  testln(0.8);
  return 0;
}

输出

2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00

[编辑]

根据@MicroVirus 的提示,我发现 double cf = 1.88*n - 0.95;double cf = 1.0; 更有效。随着使用的术语越多,所使用的值所产生的差异就越小,但是好的初始 cf 需要更少的术语才能得到好的答案,尤其是 |z| 接近 0.5 时。当我学习 0 < z <= 0.5 时,可以在这里做更多的工作。 @MicroVirus 对 2*n+1 的建议可能与我的建议很接近,因为 n 有一个偏差。

这是基于逆向计算并注意到 CF[n] 的值随着 n 的增加而得出的。我很惊讶 "seed" 值似乎不是一个很好的整数方程。

这是使用递归的问题的解决方案(如果有人感兴趣):

#include <math.h>
#include <stdio.h>

/* `i` is the iteration of the recursion and `n` is
   just for testing when we should end. 'zz' is z^2 */
double recursion (double zz, int i, int n) {
  if (!n)
    return 1;

  return 2 * i - 1 - i * i * zz / recursion (zz, i + 1, --n);
}

double contFragLog (double z, int n) {
  return 2 * z / recursion (z * z, 1, n);
}

void testln(double z) {
  double y = log((1+z)/(1-z));
  double y2 = contFragLog(z, 8);
  printf("%e %e %e\n", z, y, y2);
}

int main() {
  testln(0.2);
  testln(0.5);
  testln(0.8);
  return 0;
}

输出与上面的解决方案相同:

2.000000e-01 4.054651e-01 4.054651e-01
5.000000e-01 1.098612e+00 1.098612e+00
8.000000e-01 2.197225e+00 2.196987e+00