㈠ C語言程序設計,用級數計算圓周率π
我寫過精確10000多位的,但代碼太多無法在此列出,我給你提供一個思路:
定義長度為固定值的位元組的數組當做一個「大整數型」,長度為BI_SIZE,數組的0號數為最低8位,往後是更高8位,以此類推。
考慮計算過程中的溢出問題,BI_SIZE要盡量大,但也不能太大,否則算得會很慢。
#define
BI_SIZE
128
定義小數點後的十進制位數PI_NUM,略大於100。
#define
PI_NUM
103
這樣的數組定義多個,比如計算函數內部用的工作寄存器如下:
uint8_t
R0[BI_SIZE];
uint8_t
R1[BI_SIZE];
uint8_t
R2[BI_SIZE];
……
用戶使用的寄存器如下:
uint8_t
a0[BI_SIZE];
uint8_t
a1[BI_SIZE];
uint8_t
a2[BI_SIZE];
……
定義大整數相關處理函數,包含拷貝、清零、比大小、加、減、乘、移位、除、轉十進制ascii等函數。
比如大整數比大小,相等返回0,a大返回1,b大返回-1。
int
BigInteger_Cmp(uint8_t
*a,uint8_t
*b)
{
uint32_t
i;
for(i
=
BI_SIZE
-
1;i
<
BI_SIZE;i
--)
{
if(a[i]
!=
b[i])
{
if(a[i]
>
b[i])
return
1;
else
return
-1;
}
}
return
0;
}
凡是運算函數都要使用輸入地址的方式,如大整數相加,將a與b相加後的值裝入地址c。
void
BigInteger_Add(uint8_t
*c,uint8_t
*a,uint8_t
*b);
調用每一個函數時,輸出寄存器不能與輸入寄存器沖突。
寫除法函數可能比較難,請參考二進制除法相關資料。
列印函數可以用連續除以10求余獲得。
函數准備完成後就可以算圓周率了,先用循環算出10的PI_NUM次方作為標准系數EXP[BI_SIZE],計算每一項時分子要先乘EXP再除。由於你的級數公制性質,建議乘和除交替進行,以免數字溢出。
每一項不斷累加起來,直到當前算得的項為0為止,累加結果轉十進制列印出來。
調試時PI_NUM可以先改小,如果數字正確,就可以改為100多了。
㈡ python模擬蒙特卡羅法計算圓周率的近似值
蒙特·卡羅方法是一種通過概率來得到問題近似解的方法,在很多領域都有重要的應用,其中就包括圓周率近似值的計問題。
假設有一塊邊長為2的正方形木板,上面畫一個單位圓,然後隨意往木板上扔飛鏢,落點坐標(x,y)必然在木板備肢上(更多的時候是落在單位圓內),
如果扔仿喚世的次數足夠多,那麼落在單位鏈宴圓內的次數除以總次數再乘以4,這個數字會無限逼近圓周率的值。
這就是蒙特·卡羅發明的用於計算圓周率近似值的方法。
編寫程序,模擬蒙特·卡羅計算圓周率近似值的方法,輸入擲飛鏢次數,然後輸出圓周率近似值。
import random,math
s = 1 * 1
c = int(input())
hit = c
hits = 0
while hit != 0 :
hit = hit - 1
x = random.random()
y = random.random()
z = math.sqrt(x**2+y**2)
if z <= 1:
hits = hits + 1
PI = 4 * hits/c
print(PI)
這段程序主要運用通過計算落點的坐標與原點的距離來確定鏢是否在中在圓內
當運行的次數足夠大,也就會越來越逼近圓周率
另外再說一點就是python中的random()函數
random()函數的調用方法如下
import random
x = random.random()
返回的值在(0,1]之間
㈢ C語言計算圓周率
#include<stdio.h>
#include<math.h>
intmain(){
doublep=0,q=0;
inti;
for(i=1;;i++){
p+=6*1.0/(i*i);
q+=4*1.0*pow(-1,i+1)/(2*i-1);//q後面少一個版+
if(fabs(sqrt(p)-q)<1e-6)
break;
}
printf("PIis%lf,項數權為%d",q,i);
return0;
}
㈣ 那個計算π的C語言程序是怎麼寫的啊
1、PI的值可以通過以下公式計算出來,
π/4=1-1/3+1/5-1/7……
編寫循環程序,當這種計算方法所得到的偏差小於0.000001時停止計算,並輸出PI的值及所需要計算的項數。
2、常式:
doubles=0;//面積
doublepi=0;//圓周率
doubled=200;//直徑(值越大圓周率越精確)
doubler=d/2;//半徑
for(inti=1;i<=d;i++){
for(intj=1;j<=d;j++){
if((i-r)*(i-r)+(j-r)*(j-r)<=r*r){
s++;
}
}
}
pi=s/(r*r);
㈤ 編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語言編程求出圓周率的近似值。
#include <stdio.h>
int main()
{
double pi;
unsigned long i,n;
scanf("%lu",&n);
for(pi=1,i=1;i<=n;++i)
{
pi*=(i+1)/2*2.0 / ( (i+1)/2*2+(i-1)%2*2-1 );
}
printf("pi=%.10lf ",pi*=2);
return 0;
}
㈦ 用C語言編寫一個求圓周率的程序
#include<stdio.h>
main()
{ float s,r,PI;
clrscr();
printf("input周長 s");
scanf("%f",&s);
printf("input半徑 r");
scanf("%f",&r);
PI=s/(2*r);
pringf("周長=%f,半徑=%f\n圓周率PI=%f",s,r,PI);
}
㈧ 編寫程序:計算π的近似值,π的計算公式為
#include<stdio.h>
main()
{ int n,i; double t,
sum;/*1*/
printf("請輸入n的值 ");
scanf("%d",&n);
sum=2; i=1; t=2;/*2*/
while(i<n) { t=t*(2*i)*(2*i)/(2*i-1)/(2*i+1);
/*3*/ // sum=sum*t; i=i+1; }
printf("π的值=%f ",t);/*4*/ }
或。
寫一個java程序來實現蒙特卡洛法求π的近似值:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class MonteCarloPi {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("How many darts shoud I toss at the board? ");
String s = br.readLine();
int numberOfDarts = Integer.parseInt(s.trim());
double radius = 1.0;
Dartboard d = new Dartboard(radius);
for(int i=1; i<=numberOfDarts; i++){
Toss t = Toss.getRandom(radius);
d.strike(t);
}
double fractionIn = d.getFractionIn();
double pi = 4.0 * fractionIn;
System.out.println("Pi is approximately "+pi);
}
}
class Dartboard{
private double radius;
private int insideCircle, outsideCircle;
public Dartboard(double radius){
this.radius = radius;
insideCircle = 0;
outsideCircle = 0;
}
public void strike(Toss toss){
double x = toss.getX();
double y = toss.getY();
if(Math.sqrt(x*x + y*y) < radius)
insideCircle++;
else
outsideCircle++;
}
public double getFractionIn() {
double total = (double) (insideCircle + outsideCircle);
return (double) insideCircle/total;
}
}
class Toss{
private double x,y;
public Toss(double x, double y){
this.x = x;
this.y = y;
}
public double getX(){return x;}
public double getY(){return y;}
public static Toss getRandom(double radius){
double x,y;
double size = Math.random();
double sign = Math.random();
size = size * radius;
if(sign > 0.5)
x = size;
else
x = -size;
size = Math.random();
sign = Math.random();
size = size * radius;
if(sign > 0.5)
y = size;
else
y = -size;
return new Toss(x,y);
}
}
(8)請編寫程序計算圓周率擴展閱讀:
C語言:用循環結構分別編寫程序
#include
void main()
{
x09int n=1;
x09float temp;
x09float sum=0;
x09do
x09{
x09x09temp=(float)1/(2*n-1);
x09x09if(n%2==1)
x09x09x09sum+=temp;
x09x09else
x09x09x09sum-=temp;
x09x09n++;
x09}while(temp>=0.000001);
x09printf("Pi=%f ",sum*4);
}
㈨ 編寫程序:計算π的近似值,π的計算公式為
#include<stdio.h>
main()
{ int n,i; double t,
sum;/*1*/
printf("請輸入n的值 ");
scanf("%d",&n);
sum=2; i=1; t=2;/*2*/
while(i<n) { t=t*(2*i)*(2*i)/(2*i-1)/(2*i+1);
/*3*/ // sum=sum*t; i=i+1; }
printf("π的值=%f ",t);/*4*/ }
或。
寫一個Java程序來實現蒙特卡洛法求π的近似值:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class MonteCarloPi {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("How many darts shoud I toss at the board? ");
String s = br.readLine();
int numberOfDarts = Integer.parseInt(s.trim());
double radius = 1.0;
Dartboard d = new Dartboard(radius);
for(int i=1; i<=numberOfDarts; i++){
Toss t = Toss.getRandom(radius);
d.strike(t);
}
double fractionIn = d.getFractionIn();
double pi = 4.0 * fractionIn;
System.out.println("Pi is approximately "+pi);
}
}
class Dartboard{
private double radius;
private int insideCircle, outsideCircle;
public Dartboard(double radius){
this.radius = radius;
insideCircle = 0;
outsideCircle = 0;
}
public void strike(Toss toss){
double x = toss.getX();
double y = toss.getY();
if(Math.sqrt(x*x + y*y) < radius)
insideCircle++;
else
outsideCircle++;
}
public double getFractionIn() {
double total = (double) (insideCircle + outsideCircle);
return (double) insideCircle/total;
}
}
class Toss{
private double x,y;
public Toss(double x, double y){
this.x = x;
this.y = y;
}
public double getX(){return x;}
public double getY(){return y;}
public static Toss getRandom(double radius){
double x,y;
double size = Math.random();
double sign = Math.random();
size = size * radius;
if(sign > 0.5)
x = size;
else
x = -size;
size = Math.random();
sign = Math.random();
size = size * radius;
if(sign > 0.5)
y = size;
else
y = -size;
return new Toss(x,y);
}
}
(9)請編寫程序計算圓周率擴展閱讀:
C語言:用循環結構分別編寫程序
#include
void main()
{
x09int n=1;
x09float temp;
x09float sum=0;
x09do
x09{
x09x09temp=(float)1/(2*n-1);
x09x09if(n%2==1)
x09x09x09sum+=temp;
x09x09else
x09x09x09sum-=temp;
x09x09n++;
x09}while(temp>=0.000001);
x09printf("Pi=%f ",sum*4);
}
㈩ vb編程 算圓周率
圓周率π,在vb
編程中,你用健盤是輸入不到這個值的,你得用一個常數來定義它的值,如計算圓的體積v=4/3*π*r*r*r,且設r為2,可以用下面的程序代碼來編寫:
(方法一):let
p=3.141592
let
r=2
let
v=4/3*p*r*r*r
print
v
end
(方法二):const
p=3.141592
let
r=2
let
v=4/3*p*r^3
print
v
end
說明:第二個是利用符號常量來代表∏,也就是用函數const定義了p的值,p的值變成了常量,此時在程序中不允許再賦新值