为什么我计算pi数的函数冻结了?

问题描述

我需要计算pi的数字直到第15位,但是我的函数冻结了。我使用泰勒的这个系列:

atan(x) = \sum_{n=0}^\infty \frac{(-1)^{n} \cdot x^{2n + 1}}{2n + 1}

enter image description here

x等于1。

有我的功能

public static decimal Pi()
{
   decimal curr = 4m,prev = 0m,one = -1m,den = 3.0m;

   while (Math.Abs(curr - prev) > 1e-15m)
   {
      prev = curr;
      curr += 4.0m * one / den;
      one = -one;
      den += 2.0m;
   }
        
   return curr;
}

我已经调试了,但是我没有找到原因。链接REPL

解决方法

问题在于该算法对所需精度的位数呈指数关系。为了证明我已经对您的代码进行了一些更改,以便在我们获得越来越精确的结果之前跟踪迭代次数

let deadline = Moment(game.deadline);
        
let timeUntilDeadline = Moment.duration( Moment(deadline,"YYYY-M-D HH:mm:ss").diff(Moment()));
        
let deadline_formatted = timeUntilDeadline.format("d[d] h[h] m[m]",{ trim: "all" });

这是达到8位精度后的结果输出。

decimal curr = 4m,prev = 0m,one = -1m,den = 3.0m;

int i = 0;
decimal epsilon = 1;

while(true)
{
  prev = curr;
  curr += 4.0m * one / den;
  one = -one;
  den += 2.0m;
  
  i++;
  
  if(Math.Abs(curr - prev) <= epsilon)
  {
    Console.WriteLine(curr);
    Console.WritleLine(i);
    epsilon /= 10m;
  } 
 
}

您会看到,每增加一位精确度,其迭代次数就将增加10倍,因此,获得15位精确度将达到10倍,而获得8则迭代次数。

,

根据公式

|cur - prev| = 1 / (2n+1) + 1 / (2n-1)

您的函数应该可以正常工作,您只需要等到第250,000,000任期即可。有点耐心(只有几天)。

但是不能保证最后得到15个准确数字。


永远不要使用莱布尼茨的公式。使用Machin的变体。 https://en.wikipedia.org/wiki/Machin-like_formula