如何在C语言中实现连分数自然对数?
这里我有一个小问题。从这个公式中创建一些东西: 这就是我所拥有的,但它不起作用。弗兰基,我真的不明白该怎么做。。我试图用一些糟糕的指令来编写代码。N是迭代次数和分数的部分。我认为它会导致递归,但不知道如何 谢谢你的帮助如何在C语言中实现连分数自然对数?,c,algorithm,function,formula,logarithm,C,Algorithm,Function,Formula,Logarithm,这里我有一个小问题。从这个公式中创建一些东西: 这就是我所拥有的,但它不起作用。弗兰基,我真的不明白该怎么做。。我试图用一些糟糕的指令来编写代码。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
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
比双cf=1.0更有效代码>。使用的术语越多,所用的值差别就越小,但是好的初始值cf
需要的术语就越少,尤其是接近0.5的|z
。当我研究0
我没有检查循环,但最终结果计算错误。您不想返回(1+cf)/(1-cf)
。该公式计算log((1+z)/(1-z))
。因此,如果您想要log(x)
,您必须计算z
的值为x=(1+z)/(1-z)
,然后根据z
进行计算(我假设您已经这样做了,公式显示了),并按原样返回结果。循环公式看起来根本不正确。不知怎的,你需要一个z*z
在那里的某个地方,但我看不到。你的b=i+i-2
与b=2*(i-1)
相同,因此你的b
总是偶数(我在公式中看到一系列奇数)。你的连分数与一不匹配。我不能确定它们是否真的不同,但你确定你显示的是正确的吗?是的,显然有更多的方法用连分数计算自然对数:)今天早些时候,一个几乎相同的问题被用户3838673发布。我回答了,但随后被OP删除。高代表用户可以看到它。也许你在同一个班级……你是如何决定以cf=1.0
为起点的?我的第一个直觉是2*n+1
,但我并没有很好的理由,我真的很好奇什么是正确的起始值。不需要递归,但是它是解决这个问题的一个很好的方法(因为它看起来像是按照您阅读的顺序计算结果),如果你计算递归之外的第一项,那么递归解就很短。哦,它真的很好。而且效果很好,谢谢!我在函数的开头添加了z=(z-1)/(z+1,现在是完美的)@微病毒真的cf=1.0代码>是一个简单的尝试<代码>2*n+1可能更好。我将考虑其他的起始值。很高兴为OP留下一些东西。很高兴看到你尝试:)谢谢你的回复。
#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