我已经得到了这个问题来解决问题。我正在努力试图绕过递归。一些细分问题会非常有用。
鉴于Pi可以使用函数4 *(1 - 1/3 + 1/5 - 1/7 + ...)进行估算,其中更多项可以提供更高的精度,可以编写一个函数来计算Pi到5的十进制精度地方。
我有一些示例代码但是我真的不明白这样输入变量的位置/原因。可能会对此代码的细分及其不准确的原因进行分析。
-module (pi).
-export ([pi/0]).
pi() -> 4 * pi(0,1,1).
pi(T,M,D) ->
A = 1 / D,
if
A > 0.00001 -> pi(T+(M*A), M*-1, D+2);
true -> T
end.
答案 0 :(得分:3)
该公式来自对tg(pi / 4)的评估,其等于1.逆:
pi/4 = arctg(1)
so
pi = 4* arctg(1).
using the technique of the Taylor series:
arctg (x) = x - x^3/3 + ... + (-1)^n x^(2n+1)/(2n+1) + o(x^(2n+1))
so when x = 1 you get your formula:
pi = 4 * (1 – 1/3 + 1/5 – 1/7 + …)
问题是找到pi的近似值,精度为0.00001(十进制5)。 Lookinq在公式,你可以注意到 在每个步骤(1 / 3,1 / 5,...)添加新术语:
这意味着每个项是pi的实际值与直到该项的评估之间的误差的上估计(术语o(x ^(2n + 1)))。 因此,可以使用它来保证递归的水平,保证近似值优于此术语。为了正确,该计划 你建议将递归的最终结果乘以4,这样就不会保证误差小于term。
查看代码:
pi() -> 4 * pi(0,1,1).
% T = 0 is the initial estimation
% M = 1 is the sign
% D = 1 initial value of the term's index in the Taylor serie
pi(T,M,D) ->
A = 1 / D,
% evaluate the term value
if
A > 0.00001 -> pi(T+(M*A), M*-1, D+2);
% if the precision is not reach call the pi function with,
% new serie's evaluation (the previous one + sign * term): T+(M*A)
% new inverted sign: M*-1
% new index: D+2
true -> T
% if the precision is reached, give the result T
end.
为确保您达到了正确的准确度,我建议将A > 0.00001
替换为A > 0.0000025
(= 0.00001/4
)
答案 1 :(得分:1)
我在这段代码中找不到任何错误,但我现在无法测试,无论如何:
T可能是“总数”,M是“乘数”,D是“除数”。 每走一步:
如果下一个术语(A = 1 / D)大于0.00001,则检查('if'在某种程度上类似于c / c ++ / java中的switch / case)。如果没有,你可以停止递归,你有你想要的5位小数。所以“if true(默认情况) - >返回T”
如果它更大,你将A乘以M,加上总数,然后将M乘以-1,将D加2,然后重复(这样你就可以得到下一个术语,再添加,依此类推)
pi(T,M,D) ->
A = 1 / D,
if
A > 0.00001 -> pi(T+(M*A), M*-1, D+2);
true -> T
end.
答案 2 :(得分:0)
我自己不知道Erlang,但从它的外观来看,你正在检查1 / D是否< 0.00001实际上你应该检查4 * 1 / D,因为4将成倍增加。例如,在你的情况下,如果1 / D是0.000003,你将停止四个功能,但你的总数实际上已经改变了0.000012。希望这可以帮助。