Erlang计算Pi到X的小数位

时间:2013-12-02 17:00:25

标签: erlang pi

我已经得到了这个问题来解决问题。我正在努力试图绕过递归。一些细分问题会非常有用。

鉴于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.

3 个答案:

答案 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。希望这可以帮助。