转自:http://blog.sina.com.cn/s/blog_93d2ceba010145a9.html
一、(精度计算——大数阶乘)
语法:int result=factorial(int n); |
参数: |
n: | n 的阶乘 |
返回值: | 阶乘结果的位数 |
注意: | |
| 本程序直接输出n!的结果,需要返回结果请保留long a[] |
| 需要 math.h |
源程序: | |
| int factorial(int n) { long a[10000]; int i,j,l,c,m=0,w; a[0]=1; for(i=1;i<=n;i++) { c=0; for(j=0;j<=m;j++) { a[j]=a[j]*i+c; c=a[j]/10000; a[j]=a[j]000; } if(c>0) {m++;a[m]=c;} } w=m*4+log10(a[m])+1; printf("\n%ld",a[m]); for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]); return w; } |
二、
(精度计算——乘法(大数乘小数))
语法:mult(char c[],char t[],int m); |
参数: |
c[]: | 被乘数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
m: | 乘数,限定10以内 |
返回值: | null |
注意: | |
| 需要 string.h |
源程序: | |
| void mult(char c[],char t[],int m) { int i,l,k,flag,add=0; char s[100]; l=strlen(c); for (i=0;i<l;i++) s[l-i-1]=c[i]-'0'; for (i=0;i<l;i++) { k=s[i]*m+add; if (k>=10) {s[i]=k;add=k/10;flag=1;} else {s[i]=k;flag=0;add=0;} } if (flag) {l=i+1;s[i]=add;} else l=i; for (i=0;i<l;i++) t[l-1-i]=s[i]+'0'; t[l]='\0'; } |
三、
(精度计算——乘法(大数乘大数))
语法:mult(char a[],char b[],char s[]); |
参数: |
a[]: | 被乘数,用字符串表示,位数不限 |
b[]: | 乘数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
返回值: | null |
注意: | |
| 空间复杂度为 o(n^2) |
| 需要 string.h |
源程序: | |
| void mult(char a[],char b[],char s[]) { int i,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0; char result[65]; alen=strlen(a);blen=strlen(b); for (i=0;i<alen;i++) for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0'); for (i=alen-1;i>=0;i--) { for (j=blen-1;j>=0;j--) sum=sum+res[i+blen-j-1][j]; result[k]=sum; k=k+1; sum=sum/10; } for (i=blen-2;i>=0;i--) { for (j=0;j<=i;j++) sum=sum+res[i-j][j]; result[k]=sum; k=k+1; sum=sum/10; } if (sum!=0) {result[k]=sum;k=k+1;} for (i=0;i<k;i++) result[i]+='0'; for (i=k-1;i>=0;i--) s[i]=result[k-1-i]; s[k]='\0'; while(1) { if (strlen(s)!=strlen(a)&&s[0]=='0') strcpy(s,s+1); else break; } } |
四、
(精度计算——加法)
语法:add(char a[],char b[],char s[]); |
参数: |
a[]: | 被乘数,用字符串表示,位数不限 |
b[]: | 乘数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
返回值: | null |
注意: | |
| 空间复杂度为 o(n^2) |
| 需要 string.h |
源程序: | |
| void add(char a[],char b[],char back[]) { int i,j,k,up,x,y,z,l; char *c; if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=strlen(b)+2; c=(char *) malloc(l*sizeof(char)); i=strlen(a)-1; j=strlen(b)-1; k=0;up=0; while(i>=0||j>=0) { if(i<0) x='0'; else x=a[i]; if(j<0) y='0'; else y=b[j]; z=x-'0'+y-'0'; if(up) z+=1; if(z>9) {up=1;z%=10;} else up=0; c[k++]=z+'0'; i--;j--; } if(up) c[k++]='1'; i=0; c[k]='\0'; for(k-=1;k>=0;k--) back[i++]=c[k]; back[i]='\0'; } |
五、(精度计算——减法)
语法:sub(char s1[],char s2[],char t[]); |
参数: |
s1[]: | 被减数,用字符串表示,位数不限 |
s2[]: | 减数,用字符串表示,位数不限 |
t[]: | 结果,用字符串表示 |
返回值: | null |
注意: | |
| 默认s1>=s2,程序未处理负数情况 |
| 需要 string.h |
源程序: | |
| void sub(char s1[],char s2[],char t[]) { int i,l2,l1,k; l2=strlen(s2);l1=strlen(s1); t[l1]='\0';l1--; for (i=l2-1;i>=0;i--,l1--) { if (s1[l1]-s2[i]>=0) t[l1]=s1[l1]-s2[i]+'0'; else { t[l1]=10+s1[l1]-s2[i]+'0'; s1[l1-1]=s1[l1-1]-1; } } k=l1; while(s1[k]<0) {s1[k]+=10;s1[k-1]-=1;k--;} while(l1>=0) {t[l1]=s1[l1];l1--;} loop: if (t[0]=='0') { l1=strlen(s1); for (i=0;i<l1-1;i++) t[i]=t[i+1]; t[l1-1]='\0'; goto loop; } if (strlen(t)==0) {t[0]='0';t[1]='\0';} } |
六、(任意进制转换)
语法:conversion(char s1[],char s2[],long d1,long d2); |
参数: |
s[]: | 原进制数字,用字符串表示 |
s2[]: | 转换结果,用字符串表示 |
d1: | 原进制数 |
d2: | 需要转换到的进制数 |
返回值: | null |
注意: | |
| 高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证 |
源程序: | |
| void conversion(char s[],char s2[],long d1,long d2) { long i,j,t,num; char c; num=0; for (i=0;s[i]!='\0';i++) { if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10; num=num*d1+t; } i=0; while(1) { t=num�; if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10; num/=d2; if (num==0) break; i++; } for (j=0;j<i/2;j++) {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;} s2[i+1]='\0'; } |
七、(最大公约数、最小公倍数)
语法:resulet=hcf(int a,int b)、result=lcd(int a,int b) |
参数: |
a: | int a,求最大公约数或最小公倍数 |
b: | int b,求最大公约数或最小公倍数 |
返回值: | 返回最大公约数(hcf)或最小公倍数(lcd) |
注意: | |
| lcd 需要连同 hcf 使用 |
源程序: | |
| int hcf(int a,int b) { int r=0; while(b!=0) { r=a%b; a=b; b=r; } return(a); } lcd(int u,int v,int h) { return(u*v/h); } |
八、(组合序列)
语法:m_of_n(int m, int n1, int m1, int* a, int head) |
参数: |
m: | 组合数C的上参数 |
n1: | 组合数C的下参数 |
m1: | 组合数C的上参数,递归之用 |
*a: | 1~n的整数序列数组 |
head: | 头指针 |
返回值: | null |
注意: | |
| *a需要自行产生 |
| 初始调用时,m=m1、head=0 |
| 调用例子:求C(m,n)序列:m_of_n(m,n,m,a,0); |
源程序: | |
| void m_of_n(int m, int n1, int m1, int* a, int head) { int i,t; if(m1<0 || m1>n1) return; if(m1==n1) { for(i=0;i<m;i++) cout<<a[i]<<' '; // 输出序列 cout<<'\n'; return; } m_of_n(m,n1-1,m1,a,head); // 递归调用 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t; m_of_n(m,n1-1,m1-1,a,head+1); // 再次递归调用 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t; } |
九、(快速傅立叶变换(FFT))
语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],int l,int il); |
参数: |
pr[n]: | 输入的实部 |
pi[n]: | 数入的虚部 |
n,k: | 满足n=2^k |
fr[n]: | 输出的实部 |
fi[n]: | 输出的虚部 |
l: | 逻辑开关,0 FFT,1 ifFT |
il: | 逻辑开关,0 输出按实部/虚部;1 输出按模/幅角 |
返回值: | null |
注意: | |
| 需要 math.h |
源程序: | |
| void kkfft(pr,pi,n,k,fr,fi,l,il) int n,k,l,il; double pr[],pi[],fr[],fi[]; { int it,m,is,i,j,nv,l0; double p,q,s,vr,vi,poddr,poddi; for (it=0; it<=n-1; it++) { m=it; is=0; for (i=0; i<=k-1; i++) {j=m/2; is=2*is+(m-2*j); m=j;} fr[it]=pr[is]; fi[it]=pi[is]; } pr[0]=1.0; pi[0]=0.0; p=6.283185306/(1.0*n); pr[1]=cos(p); pi[1]=-sin(p); if (l!=0) pi[1]=-pi[1]; for (i=2; i<=n-1; i++) { p=pr[i-1]*pr[1]; q=pi[i-1]*pi[1]; s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]); pr[i]=p-q; pi[i]=s-p-q; } for (it=0; it<=n-2; it=it+2) { vr=fr[it]; vi=fi[it]; fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1]; fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1]; } m=n/2; nv=2; for (l0=k-2; l0>=0; l0--) { m=m/2; nv=2*nv; for (it=0; it<=(m-1)*nv; it=it+nv) for (j=0; j<=(nv/2)-1; j++) { p=pr[m*j]*fr[it+j+nv/2]; q=pi[m*j]*fi[it+j+nv/2]; s=pr[m*j]+pi[m*j]; s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]); poddr=p-q; poddi=s-p-q; fr[it+j+nv/2]=fr[it+j]-poddr; fi[it+j+nv/2]=fi[it+j]-poddi; fr[it+j]=fr[it+j]+poddr; fi[it+j]=fi[it+j]+poddi; } } if (l!=0) for (i=0; i<=n-1; i++) { fr[i]=fr[i]/(1.0*n); fi[i]=fi[i]/(1.0*n); } if (il!=0) for (i=0; i<=n-1; i++) { pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]); if (fabs(fr[i])<0.000001*fabs(fi[i])) { if ((fi[i]*fr[i])>0) pi[i]=90.0; else pi[i]=-90.0; } else pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306; } return; } |
十、(Ronberg算法计算积分)
语法:result=integral(double a,double b); |
参数: |
a: | 积分上限 |
b: | 积分下限 |
function f: | 积分函数 |
返回值: | f在(a,b)之间的积分值 |
注意: | |
| function f(x)需要自行修改,程序中用的是sina(x)/x |
| 需要 math.h |
| 默认精度要求是1e-5 |
源程序: | |
| double f(double x) { return sin(x)/x; //在这里插入被积函数 } double integral(double a,double b) { double h=b-a; double t1=(1+f(b))*h/2.0; int k=1; double r1,r2,s1,s2,c1,c2,t2; loop: double s=0.0; double x=a+h/2.0; while(x<b) { s+=f(x); x+=h; } t2=(t1+h*s)/2.0; s2=t2+(t2-t1)/3.0; if(k==1) { k++;h/=2.0;t1=t2;s1=s2; goto loop; } c2=s2+(s2-s1)/15.0; if(k==2){ c1=c2;k++;h/=2.0; t1=t2;s1=s2; goto loop; } r2=c2+(c2-c1)/63.0; if(k==3){ r1=r2; c1=c2;k++; h/=2.0; t1=t2;s1=s2; goto loop; } while(fabs(1-r1/r2)>1e-5){ r1=r2;c1=c2;k++; h/=2.0; t1=t2;s1=s2; goto loop; } return r2; } |
十一、(行列式计算)
对角线展开:
|a1 b1| =a1b2-a2b1
|a2 b2|
|a1 b1 c1|
|a2 b2 c2|=a1b2c3+b1c2a3+c1a2b3-a3b2c1-b3c2a1-c3a2b1
|a3 b3 c3|
降阶展开(适合高阶行列式)
如三阶行列式 按第一阶展开
|a b c|
|d e f |=a×|e f|-b×|d f|+c×|d e|
|g h i | |h i| |g i| |g h|
按中阶展开
以上行列式=e×|a c|-d×|b c|-f×|a b|
|g i| |h i| |g h|
其他行列式计算相仿
语法:result=js(int s[][],int n) |
参数: |
s[][]: | 行列式存储数组 |
n: | 行列式维数,递归用 |
返回值: | 行列式值 |
注意: | |
| 函数中常数N为行列式维度,需自行定义 |
源程序: | |
| int js(s,n) int s[][N],n; { int z,j,k,r,total=0; int b[N][N]; if(n>2) { for(z=0;z<n;z++) { for(j=0;j<n-1;j++) for(k=0;k<n-1;k++) if(k>=z) b[j][k]=s[j+1][k+1]; else b[j][k]=s[j+1][k]; if(z%2==0) r=s[0][z]*js(b,n-1); else r=(-1)*s[0][z]*js(b,n-1); total=total+r; } } else if(n==2) total=s[0][0]*s[1][1]-s[0][1]*s[1][0]; return total; } |
十二、(求排列组合数)
语法:result=P(long n,long m); / result=long C(long n,long m); |
参数: |
m: | 排列组合的上系数 |
n: | 排列组合的下系数 |
返回值: | 排列组合数 |
注意: | |
| 符合数学规则:m<=n |
源程序: | |
| long P(long n,long m) { long p=1; while(m!=0) {p*=n;n--;m--;} return p; } long C(long n,long m) { long i,c=1; i=m; while(i!=0) {c*=n;n--;i--;} while(m!=0) {c/=m;m--;} return c; } |