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多了。
计算圆周率的C语言程序
#include stdio.h
#define L 10000 //求10000位PI值
#define N L/4+1
// L 为位数,N是array长度
/*圆周率后的小数位数是无止境的,如何使用电脑来计算这无止境的小数是一些数学家与程式设计师所感兴趣的,在这边介绍一个公式配合 大数运算,可以计算指定位数的圆周率。
John Wallis的圆周率公式:
//详细看网站介绍:
PI = [16/5 – 16 / (3*53) + 16 / (5*55) – 16 / (7*57) + ……] – [4/239 – 4/(3*2393) + 4/(5*2395) – 4/(7*2397) + ……]
*/
void add ( int*, int*, int* );
void sub ( int*, int*, int* );
void div ( int*, int, int* );
int main ( void )
{
int s[N+3] = {0};
int w[N+3] = {0};
int v[N+3] = {0};
int q[N+3] = {0};
int n = ( int ) ( L/1.39793 + 1 );
int k;
w[0] = 16*5;
v[0] = 4*239;
for ( k = 1; k = n; k++ )
{
// 套用公式
div ( w, 25, w );
div ( v, 239, v );
div ( v, 239, v );
sub ( w, v, q );
div ( q, 2*k-1, q );
if ( k%2 ) // 奇数项
add ( s, q, s );
else // 偶数项
sub ( s, q, s );
}
printf ( “%d.”, s[0] );
for ( k = 1; k N; k++ )
printf ( “%04d”, s[k] );
printf ( “\n” );
return 0;
}
void add ( int *a, int *b, int *c )
{
int i, carry = 0;
for ( i = N+1; i = 0; i– )
{
c[i] = a[i] + b[i] + carry;
if ( c[i] 10000 )
carry = 0;
else // 进位
{
c[i] = c[i] – 10000;
carry = 1;
}
}
}
void sub ( int *a, int *b, int *c )
{
int i, borrow = 0;
for ( i = N+1; i = 0; i– )
{
c[i] = a[i] – b[i] – borrow;
if ( c[i] = 0 )
borrow = 0;
else // 借位
{
c[i] = c[i] + 10000;
borrow = 1;
}
}
}
void div ( int *a, int b, int *c ) // b 为除数
{
int i, tmp, remain = 0;
for ( i = 0; i = N+1; i++ )
{
tmp = a[i] + remain;
c[i] = tmp / b;
remain = ( tmp % b ) * 10000;
}
}
C语言计算圆周率
#include stdio.h
double fact(int n)
{
double res = 1.0;
for(int i = 1; i = n; i++)
res *= i;
return res;
}
double multi(int n)
{
double res = 1.0;
for(int i = 1; i = n; i += 2)
res *= i;
return res;
}
int main()
{
double sum=1.0, item=1.0, eps = 1e-6;
for(int i = 1; item = eps; i++)
{
item = fact(i) / multi(2*i + 1);
sum = sum + item;
}
printf(“PI=%0.5lf\n”, sum * 2);
return 0;
}
//这样可以得到3.14159
用C语言编一个计算圆周率的程序,用户输入指定位数,并计算到指定位数(精度不够可以用整数)
#include “stdio.h”
#include stdlib.h
#include string.h
int main(int argc,char *argv[]){
int a,b,c,d,e,f[2801],g,i,n;
char pi[801]=””,t[5]=””;
for(a=10000,b=0,c=2800;b-c;f[b++]=2000);//a/5
for(i=e=0;d=0,g=c*2;c-=14,e=d%a){
for(b=c;d+=f[b]*a,f[b]=d%–g,d/=g–,–b;d*=b);
n=e+d/a,t[0]=t[1]=t[2]=t[3]=’\0′;
n10 ? t[0]=t[1]=t[2]=’0′,i=3 : n100 ? t[0]=t[1]=’0′,i=2 : n1000 ? t[0]=’0′,i=1 : i=0;
itoa(n,t+i,10);
strcat(pi,t);
}
printf(“Please enter the length n(int 0n800)…\nn=”);
if(scanf(“%d”,n)!=1 || n1 || n800){
printf(“Input error, exit…\n”);
return 0;
}
for(i=0;in;printf(“%c”,pi[i++]));
printf(“\n”);
return 0;
}
代码格式和运行样例图片: