計算圓周率 Pi (π)值, 精確到小數點後 10000 位(C語言)

來源:互聯網
上載者:User

大家都知道π=3.1415926……無窮多位, 曆史上很多人都在計算這個數, 一直認為是一個非常複雜的問題。現在有了電腦, 這個問題就簡單了。
電腦可以利用級數計算出很多高精度的值, 有關級數的問題請參考《高等數學》,以下是比較有名的有關π的級數:

其中有些計算起來很複雜, 我們可以選用第三個, 比較簡單, 並且收斂的非常快。
因為計算π值, 而這個公式是計算π/2的, 我們把它變形:
π = 2 + 2/3 + 2/3*2/5 + 2/3*2/5*3/7 + ...

--------------------------------------------------------------------------------

對於級數, 我們先做個簡單測試, 暫時不要求精度:
用 C++ Builder 建立一個工程, 在 Form 上放一個 Memo1 和 一個 Button1, 在 Button1 的 OnClick 事件寫:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
double x=2, z=2;
int a=1, b=3;
while(z>1e-15)
{
    z = z*a/b;
    x += z;
    a++;
    b+=2;
}
Memo1->Text = AnsiString().sprintf("Pi=%.13f", x);
}

按Button1在Memo1顯示出執行結果:

Pi=3.1415926535898

--------------------------------------------------------------------------------

這個程式太簡單了, 而且 double 的精度很低, 只能計算到小數點後 10 幾位。
把上面的程式改造一下, 讓它精確到小數點後面 1000 位再測試一下:
在 Form 上再放一個按鈕 Button2, 在這個按鈕的 OnClick 事件寫:

void __fastcall TForm1::Button2Click(TObject *Sender)
{
const ARRSIZE=1010, DISPCNT=1000; //定義數組大小,顯示位元
char x[ARRSIZE], z[ARRSIZE]; //x[0] x[1] . x[2] x[3] x[4] .... x[ARRSIZE-1]
int a=1, b=3, c, d, Run=1, Cnt=0;

memset(x,0,ARRSIZE);
memset(z,0,ARRSIZE);

x[1] = 2;
z[1] = 2;

while(Run && (++Cnt<200000000))
{
    //z*=a;
    d = 0;
    for(int i=ARRSIZE-1; i>0; i--)
    {
      c = z[i]*a + d;
      z[i] = c % 10;
      d = c / 10;
    }
    //z/=b;
    d = 0;
    for(int i=0; i<ARRSIZE; i++)
    {
      c = z[i]+d*10;
      z[i] = c / b;
      d = c % b;
    }
    //x+=z;
    Run = 0;
    for(int i=ARRSIZE-1; i>0; i--)
    {
      c = x[i] + z[i];
      x[i] = c%10;
      x[i-1] += c/10;
      Run |= z[i];
    }
    a++;
    b+=2;
}
Memo1->Text = AnsiString().sprintf("計算了 %d 次/r/n",Cnt);
Memo1->Text = Memo1->Text + AnsiString().sprintf("Pi=%d%d./r/n", x[0],x[1]);
for(int i=0; i<DISPCNT; i++)
{
    if(i && ((i%100)==0))
    Memo1->Text = Memo1->Text + "/r/n";
    Memo1->Text = Memo1->Text + (int)x[i+2];
}
}

按 Button2 執行結果:

Pi=03.
1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196
4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273
7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094
3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912
9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132
0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235
4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859
5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303
5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989

--------------------------------------------------------------------------------

這下心理有底了, 是不是改變數組大小就可以計算更多位元呢?答案是肯定的。
如果把定義數組大小和顯示位元改為:

const ARRSIZE=10100, DISPCNT=10000; //定義數組大小,顯示位元

執行結果精度可達 10000 位:

Pi=03.
1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196
4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273
7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094
3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912
9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132
0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235
4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859
5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303
5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989
3809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151

... 限於篇幅, 這裡就省略了, 還是留給你自己來算吧!

5020141020672358502007245225632651341055924019027421624843914035998953539459094407046912091409387001
2645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678

--------------------------------------------------------------------------------

提高精度的原理:

以上程式的原理是利用數組把計算結果儲存起來, 其中數組每一項儲存10進位數的一位,
小數點定位在數組第1個數和第二個數之間, 即小數點前面2位整數, 其餘都是小數位。

利用電腦類比四則運算的筆算方法來實現高精度的資料計算,沒想到最原始的方法竟然是精度最高的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.