當前位置:首頁 » 編程語言 » c語言求派的精度
擴展閱讀
怎麼屏蔽硬碟壞道 2022-11-27 00:15:50
C語言中如何計算因子 2022-11-27 00:14:43
雲存儲的網址怎麼保存 2022-11-27 00:13:41

c語言求派的精度

發布時間: 2022-10-03 09:34:40

① 用c語言編個程序,求π(派)

利用「正多邊形逼近」的方法求出π的近似值

*程序說明與注釋
#include<stdio.h>
#include<math.h>
int main()
{
double e=0.1,b=0.5,c,d;
long int i; /*i: 正多邊形邊數*/
for(i=6;;i*=2) /*正多邊形邊數加倍*/
{
d=1.0-sqrt(1.0-b*b); /*計算圓內接正多邊形的邊長*/
b=0.5*sqrt(b*b+d*d);
if(2*i*b-i*e<1e-15) break; /*精度達1e-15則停止計算*/
e=b; /*保存本次正多邊形的邊長作為下一次精度控制的依據*/
}
printf("pai=%.15lf\n",2*i*b); /*輸出π值和正多邊形的邊數*/
printf("The number of edges of required polygon:%ld\n",i);
}

*問題分析與演算法設計
利用「正多邊形逼近」的方法求出π值在很早以前就存在,我們的先人祖沖之就是用這種方法在世界上第一個得到精確度達小數點後第6位的π值的。
利用圓內接正六邊形邊長等於半徑的特點將邊數翻番,作出正十二邊形,求出邊長,重復這一過程,就可獲得所需精度的π的近似值。
假設單位圓內接多邊形的邊長為2b,邊數為i,則邊數加倍後新的正多邊形的邊長為:
x=√——————
2-2*√———
1-b*b
——————
2
周長為:
y=2 * i * x i:為加倍前的正多邊形的邊數

② 編C語言程序計算圓周率π,要求精確到2000位,用命令行參數實現

關鍵是數學知識,而不是計算機的知識...
http://hi..com/sunlovestar/blog/item/36fad5a20e12c1accaefd051.html

一、源程序
本文分析下面這個很流行的計算PI的小程序。下面這個程序初看起來似乎摸不到頭腦,
不過不用擔心,當你讀完本文的時候就能夠基本讀懂它了。
程序一:很牛的計算Pi的程序
int a=10000,b,c=2800,d,e,f[2801],g;
main() {
for(;b-c;)
f[b++]=a/5;
for(;d=0,g=c*2;c -=14,printf("%.4d",e+d/a),e=d%a)
for(b=c; d+=f[b]*a,f[b]=d%--g,d/=g--,--b; d*=b);
}
二、數學公式
數學家們研究了數不清的方法來計算PI,這個程序所用的公式如下:
1 2 3 k
pi = 2 + --- * (2 + --- * (2 + --- * (2 + ... (2 + ---- * (2 + ... ))...)))

3 5 7 2k+1
至於這個公式為什麼能夠計算出PI,已經超出了本文的能力范圍。
下面要做的事情就是要分析清楚程序是如何實現這個公式的。
我們先來驗證一下這個公式:
程序二:Pi公式驗證程序
#include "stdio.h"
void main()
{
float pi=2;
int i;
for(i=100;i>=1;i--)
pi=pi*(float)i/(2*i+1)+2;
printf("%f\n",pi);
getchar();
}
上面這個程序的結果是3.141593。
三、程序展開
在正式分析程序之前,我們需要對程序一進行一下展開。我們可以看出程序一都是使用
for循環來完成計算的,這樣做雖然可以使得程序短小,但是卻很難讀懂。根據for循環
的運行順序,我們可以把它展開為如下while循環的程序:
程序三:for轉換為while之後的程序
int a=10000,b,c=2800,d,e,f[2801],g;
main() {
int i;
for(i=0;i<c;i++)
f[i]=a/5;
while(c!=0)
{
d=0;
g=c*2;
b=c;
while(1)
{
d=d+f[b]*a;
g--;
f[b]=d%g;
d=d/g;
g--;
b--;
if(b==0) break;
d=d*b;
}
c=c-14;
printf("%.4d",e+d/a);
e=d%a;
}
}
註:
for([1];[2];[3]) {[4];}
的運行順序是[1],[2],[4],[3]。如果有逗號操作符,例如:d=0,g=c*2,則先運行d=0,
然後運行g=c*2,並且最終的結果是最後一個表達式的值,也就是這里的c*2。
下面我們就針對展開後的程序來分析。
四、程序分析
要想計算出無限精度的PI,我們需要上述的迭代公式運行無數次,並且其中每個分數也
是完全精確的,這在計算機中自然是無法實現的。那麼基本實現思想就是迭代足夠多次
,並且每個分數也足夠精確,這樣就能夠計算出PI的前n位來。上面這個程序計算800位
,迭代公式一共迭代2800次。
int a=10000,b,c=2800,d,e,f[2801],g;
這句話中的2800就是迭代次數。
由於float或者double的精度遠遠不夠,因此程序中使用整數類型(實際是長整型),分
段運算(每次計算4位)。我們可以看到輸出語句 printf("%.4d",e+d/a); 其中%.4就是
把計算出來的4位輸出,我們看到c每次減少14( c=c-14;),而c的初始大小為2800,因
此一共就分了200段運算,並且每次輸出4位,所以一共輸出了800位。
由於使用整型數運算,因此有必要乘上一個系數,在這個程序中系數為1000,也就是說
,公式如下:
1 2 3 k
1000*pi = 2k+ --- * (2k+ --- * (2k+ --- * (2k+ ... (2k+ ---- * (2k+ ... )).
..)))
3 5 7 2k+1
這里的2k表示2000,也就是f[2801]數組初始化以後的數據,a=10000,a/5=2000,所以下面
的程序把f中的每個元素都賦值為2000:
for(i=0;i<c;i++)
f[i]=a/5;
你可能會覺得奇怪,為什麼這里要把一個常數儲存到數組中去,請繼續往下看。
我們先來跟蹤一下程序的運行:
while(c!=0) 假設這是第一次運行,c=2800,為迭代次數
{
d=0;
g=c*2; 這里的g是用來做k/(2k+1)中的分子
b=c; 這里的b是用來做k/(2k+1)中的分子
while(1)
{
d=d+f[b]*a; f中的所有的值都為2000,這里在計算時又把系數擴大了
a=10000倍。

這樣做的目的稍候介紹,你可以看到
輸出的時候是d/a,所以這不影
計算
g--;
f[b]=d%g; 先不管這一行
d=d/g; 第一次運行的g為2*2799+1,你可以看到g做了分母
g--;
b--;
if(b==0) break;
d=d*b; 這里的b為2799,可以看到d做了分子。
}
c=c-14;
printf("%.4d",e+d/a);
e=d%a;
}
只需要粗略的看看上面的程序,我們就大概知道它的確是使用的那個迭代公式來計算Pi
的了,不過不知道到現在為止你是否明白了f數組的用處。如果沒有明白,請繼續閱讀。

d=d/g,這一行的目的是除以2k+1,我們知道之所以程序無法精確計算的原因就是這個除
法。即使用浮點數,答案也是不夠精確的,因此直接用來計算800位的Pi是不可能的。那
么不精確的成分在哪裡?很明顯:就是那個余數d%g。程序用f數組把這個誤差儲存起來
,再下次計算的時候使用。現在你也應該知道為什麼d=d+f[b]*a;中間需要乘上a了吧。
把分子擴大之後,才好把誤差精確的算出來。
d如果不乘10000這個系數,則其值為2000,那麼運行d=d/g;則是2000/(2*2799+1),這
種整數的除法答案為0,根本無法迭代下去了。
現在我們知道程序就是把余數儲存起來,作為下次迭代的時候的參數,那麼為什麼這么
做就可以使得下次迭代出來的結果為
接下來的4位數呢?
這實際上和我們在紙上作除法很類似:
0142
/——------
7 / 1
10
7
---------------
30
28
---------------
20
14
---------------
60
.....
我們可以發現,在做除法的時候,我們通常把余數擴大之後再來計算,f中既然儲存的是
余數,而f[b]*a;則正好把這個余數擴大了a倍,然後如此循環下去,可以計算到任意精
度。
這里要說明的是,事實上每次計算出來的d並不一定只有4位數,例如第一次計算的時候
,d的值為31415926,輸出4位時候,把低四位的值儲存在e中間,e=d%a,也就是5926。

最後,這個c=c-14不太好理解。事實上沒有這條語句,程序計算出來的仍然正確。只是
因為如果迭代2800次,無論分數如何精確,最後Pi的精度只能夠達到800。
你可以把程序改為如下形式嘗試一下:
for(i=0;i<800;i++)
{
d=0;
g=c*2;
b=c;
while(1)
{
d=d+f[b]*a;
g--;
f[b]=d%g;
d=d/g;
g--;
b--;
if(b==0) break;
d=d*b;
}
// c=c-14; 不要這句話。
printf("%.4d",e+d/a);
e=d%a;
}
最後的答案仍然正確。
不過我們可以看到內循環的次數是c次,也就是說每次迭代計算c次。而每次計算後續位
數的時候,迭代次數減少14,而不影響精度。為什麼會這樣,我沒有研究。另外最後的
e+d/a,和e=d/a的作用就由讀者自己考慮吧。

③ c語言求PI值,使其精度小於0.005,為什麼運行不到結果啊,求高人解釋

幫你研究了下 問題有兩點
一 、while(j>=eps) 這句話的時候 j沒初始化沒有被賦值 怎麼比啊?
建議改一下:
while(j>=eps)
{
t=t*i;
s=s*(2*i+1);
j=1.0*t/s;
sum=sum+j;
i++;
}
return sum*2;
}
改成 do while
do
{
t=t*i;
s=s*(2*i+1);
j=1.0*t/s;
sum=sum+j;
i++;
}
return sum*2;
}while(j>=eps);

二、本程序當輸入的精度 很精時 ,會發生溢出 當然這時候系統不會提示你溢出 而回運行得到錯誤的結果 即 你說的 不會的3.14.。。啊好像是3.09.。。

s=s*(2*i+1); //s 發生溢出了
故修改成:int i=1,s=1,t=1;------》double i=1,s=1,t=1; 這樣就不會溢出了 ,隨著精度的精確 越來越接近3.1415926
你可以試一下
好的話
請採納

④ 急啊!請編寫一個C語言程序,根據以下公式求π的值(要求滿足精度0.0005,即某項小於0.0005時停止迭代)

#include <stdio.h>
#include <math.h>
double fun(double eps)
{
double s=1.0;float t=1,pi=0,n=1.0;
while((fabs(s))>=eps)
{
pi+=s;
t=n/(2*n+1);
s*=t;n++;
}
pi=pi*2;
return pi;
}
main()
{ double x;
printf("Input eps:");
scanf("%lf",&x); printf("\neps=%lf, PI=%lf\n",x,fun(x));
}

⑤ C語言求 π

C 語言是一種編譯型語言, 每個程式執行時都從 main 函數開始執行, 所以每個 C 語言程序都必須包含一個且只能包含一個 main 函數, C 語言的語句每條語句以 ";" 作為結束符, 程式的寫法可以不拘泥與格式, 但是要想寫出好程式, 需要盡可能的每條語句分開, 寫出自己和別人都能看懂的程式, C 語言本身提供了一些標準的函數庫, 用來簡化 C 程序的編寫, 例如: stdio.h, 是 Standard Input Output (標准輸入輸出庫), math.h 是 Math (數學函數庫), 函數庫所有定義的函數都會在 head (頭文件) ".h" 中聲明, 在使用標准頭文件時, 要使用 C 語言編譯器預處理關鍵字 #include (包含), C 語言的程序會在編譯自動加入根據頭文件的聲明連接你在編程中使用的庫函數, C 語言提供五種不同類型的數據類型, int (integter 整數型), float (浮點型), char (character 字元型), void (無值型), bool (boolean 布爾型), 提供基本的判斷語句 if ... else, 循環結構 for, while, do.. while 和多分枝結構 switch, C 語言還提供兩種寫給別人幫助理解方式注釋方式, 第一種是使用 // (雙斜杠) 後面加註釋內容, 注釋內容僅限於本行的結束, 第二種是 /* ... */ (省略號中間是注釋的內容) (單斜杠加星號開始, 星號加單斜杠結束) 的塊注釋.

以上的給你大概了解, 下面是對你的程式的等價變化, 和注釋

#include <stdio.h> // 包含標注輸入輸出頭文件
#include <math.h> // 包含數學函數頭文件

int main() // main 函數, 是函數執行進入點
{
int s = 1; // 定義一個整數型變數 s, 並賦值初始值 1

float n, t, pi; // 定義三個浮點型變數 n, t, pi, 多個相同的定義可以寫在一起用逗號作為分隔符

t = 1; // 給浮點型變數 t 賦值初始值 1

pi = 0; // 給浮點型變數 pi 賦值初始值 0

n = 1.0; // 給浮點型變數 n 賦值初始值 1

/* 下面的 fabs(t) 是調用 math 函數庫裡面的去絕對值函數, 這個值和1e-6 (表示1.0乘以10負六次方), 表示一個很小的值, 浮點數比較時, 和很小的數相比, 表示近似等於 0, while 是循環語句, 是下面的大括弧裡面的是否執行的條件

*/

while (fabs(t) < 1e-6)

{

pi = pi+t; // 將 pi 原來值加上 t, 所得值再賦值給 pi, 第一次執行, t 就是 1

n = n+2; // 和上面的相同的含義

s = -s; // 取 s 原值的相反數, 再賦值給 s

t = s / n; // t 取新的值, 作為下次循環的判斷條件, 給下一次次執行 t 作預備

}

pi = pi * 4; // 以上計算的是π/4的值, 乘以4的得到π

printf("pi=%10.6f\n", pi); // 調用標准輸出函數printf, 參數"pi=%10.6f\n" 是格式化輸出的格式
return 0; // 表示程序執行成功

}

以上只是大概的解釋, 在看看書, 了解吧

⑥ 用C語言求π

你的程序是模擬大量隨機事件來求pi的近似值。有兩點給你糾正的:

1、

x=(double)(rand()%10000);

y=(double)(rand()%10000);

x/、y都是小於10000的數表示(x,y)這個隨機點是落在了長10000,寬10000的矩形也就是正方形中,所以if(x*x+y*y<=10000*1000)表示這個點落在了以10000為半徑的圓內,所以,你的

if(x*x+y*y<=1)應該改為if(x*x+y*y<=10000000)。

2、

pi=(double)(a/MAX)*4.0;

pi=(double)(a/MAX)*4.0;由於MAX是10000,a<=9999,所以a永遠小於MAX所以(a/MAX)永遠等於0,所以你求出的pi值永遠等於0。pi=(double)(a/MAX)*4.0等價於pi=(double)(0)*4.0等價於pi=0;在c語言或者c++中兩個int型的變數相除結果還是int型的,如果分母大於分子結果則為0,java中好像也是的。但是分子分母中只要有一者是double或floati型的,那個整型會自動向高精度的數據類型轉換。所以你的pi=(double)(a/MAX)*4.0;應更正為pi=a/(double)MAX *4.0;或者

pi=(double)a/MAX*4/0;或者把double替換為float也可以滴

在我的機器上最終模擬出的pi的近似值是

⑦ 如何用C語言得出派值,數學老師要求精確到小數點後十位!

#include "stdio.h"
void main(void){
double pai,nDec,tmp;
int i;
nDec=1.0/10000000000;
for(pai=0,i=1;(tmp=1.0/i)>nDec;pai+=tmp,i+=4);
for(i=3;(tmp=1.0/i)>nDec;pai-=tmp,i+=4);
printf("pai=%.10f\n",4*pai);
}

⑧ c語言求π的精度問題

算π沒那麼麻煩吧??你那個問題出在類型轉換上,可以統一用double,但是用double的話模運算就不能用了哦~
另外記得求和的時候先把求和的那個變數賦值成0
給你一個我寫的成品
#include <stdio.h>
void main()
{
double i=1,k=1,pi=0;
for(;i<=10000;i++,k=-k)
pi=pi+(1/(2*i-1))*k;
pi=pi*4;
printf("%.8f\n",pi);
}

⑨ C語言求π,但是怎麼求都是2,esp是精度。以下是定義的函數。

問題可能出現在f,f開始為初始化,可能導致f會小於eps,這樣for循環將不會被執行到,自然就只執行了g=2.0*g,結果就始終為2了

⑩ C語言中如何取無限精度的pi

只能把它轉變為字元串來表示了。因為無論是float還是double都會溢出的。