中央環路混亂。返工。也不需要遞歸。只要先計算最深的術語,然後按照你的方式工作。
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
需要更少的條款來獲得良好的答案,特別是對於接近0.5的|z|
。當我研究0 < z <= 0.5
時,可以在這裏完成更多的工作。由於n
是錯誤的,因此微軟建議的2*n+1
可能接近我的建議。
這是基於反向計算,並注意到值CF[n]
爲n
增加。我很驚訝「種子」的價值似乎並不是一些很好的整數方程。
我沒有檢查循環,但最終的結果計算是錯誤的。你不想返回'(1 + cf)/(1-cf)'。該公式計算'log((1 + z)/(1-z))'。所以如果你想要'log(x)',你必須弄清楚'z'的值是什麼給你'x =(1 + z)/(1-z)',然後按照'z'計算我假設你已經完成並且公式顯示)並按原樣返回結果。 – lurker
循環公式看起來並不正確。不知何故,你需要一個'z * z'在那裏,但我沒有看到它。你有'b = i + i - 2'這與'b = 2 *(i - 1)'相同,因此你的'b'總是偶數(我在公式中看到一個奇數序列)。 – lurker
您的持續分數與維基百科給出的分數不匹配(https://en.wikipedia.org/wiki/Euler%27s_continued_fraction_formula)。我無法確定它們是否真的不同,但是你確定你顯示的是正確的嗎? – MicroVirus