今天给学弟学妹们讲大数问题,自己又把大数问题好好的复习了一遍,用c重新实现了一下;除法还是有点复杂,有点没搞清,所以就不误人子弟了,把大数的加法,乘法,减法,阶乘都自己写了一遍,对大数问题又加深了一点,大精度的还是要慢慢的积累,java版本的上次已经写了;加一个自己的传送门;java写真的是挺方便的啊;java大数
一些基本数据类型的范围:
int:32位整数,占4字节,-2^31~2^31-1(-21亿多~21亿多)
unsigned int:占4字节,0~2^32-1(0~42亿多) –10位数
VC的64位整数 :
__int64:占8字节,-2^63~2^63-1(-900亿亿多~900亿亿多)
unsigned __int64:占8字节,0~2^64-1(0~1800亿亿多)-20位数
G++的64位整数:
long long==__int64
unsigned long long==unsigned __int64
实数
float:占4字节,7位有效数字
double:占8字节,15位有效数字
浮点型的问题都是追求精度的,在一般情况下我们应当选择使用double,而很少用float;
所以当我们要进行计算的数超过了20位,我们就要用数组来模拟我们的计算过程了;
选取的是poj百练上的比较基础的例题,从基础的开始做,只要弄懂就好,积累自己的模板,再灵活运用;
#include <cstdio> #include <cstring> char a[220],b[220]; int c[220],d[220]; int result[240]; int main() { int i=0,j=0,lena,lenb,n; gets(a);//把数字用字符串保存输入 gets(b); memset(c,0,sizeof(c));//对数组进行初始化 memset(d,0,sizeof(d)); memset(result,0,sizeof(result)); lena=strlen(a); lenb=strlen(b); n=lena>lenb?lena:lenb; for(j=0,i=lena-1;i>=0;i--)//把字符数组倒序转换到数字数组中(满足我们的计算习惯) c[j++]=a[i]-'0'; for(j=0,i=lenb-1;i>=0;i--) d[j++]=b[i]-'0'; for(i=0;i<n;i++) { result[i]+=c[i]+d[i];//把两个数组相加 if(result[i]>=10)//处理进位 { result[i+1]++; result[i]-=10; } } i=n; int flag=0; while(!result[i])//处理前端零 { if(i==0) { flag=1; printf("0"); } i--; } while(i>=0&&flag==0) { printf("%d",result[i]); i--; } printf("\n"); return 0; }
#include <cstdio> #include <cstring> char a[220],b[220]; int c[220],d[220]; int result[440]; int main() { int i=0,j=0,lena,lenb,n; gets(a);//把数字用字符串保存输入 gets(b); memset(c,0,sizeof(c));//对数组进行初始化 memset(d,0,sizeof(d)); memset(result,0,sizeof(result)); lena=strlen(a); lenb=strlen(b); n=lena>lenb?lena:lenb; for(j=0,i=lena-1;i>=0;i--)//把字符数组倒序转换到数字数组中(满足我们的计算习惯) c[j++]=a[i]-'0'; for(j=0,i=lenb-1;i>=0;i--) d[j++]=b[i]-'0'; for(i=0;i<lena;i++) for(j=0;j<lenb;j++) result[i+j]+=c[i]*d[j];//i*j的结果要保存在i+j的位置 for(i=0;i<n*2;i++) { if(result[i]>=10)//处理进位 { result[i+1]+=result[i]/10; result[i]%=10; } } i=n*2-1; while(result[i]==0) i--; //处理前端零 while(i>=0) { printf("%d",result[i]); i--; } return 0; }
#include <cstdio> #include <cstring> int main() { //freopen("1.txt","r",stdin); char a[220],b[220]; int c[220],d[220]; int result[240]; int n,i,j,lena,lenb; scanf("%d",&n); while(n--) { scanf("\n%s",a); getchar(); scanf("%s",b); memset(c,0,sizeof(c)); memset(d,0,sizeof(d)); memset(result,0,sizeof(result)); lena=strlen(a); lenb=strlen(b); for(i=lena-1,j=0;i>=0;i--) c[j++]=a[i]-'0'; for(i=lenb-1,j=0;i>=0;i--) d[j++]=b[i]-'0'; for(i=0;i<lena;i++) result[i]=c[i]-d[i]; for(i=0;i<lena;i++) if(result[i]<0)//处理小于零的情况 { result[i]+=10;//向前一位借10; result[i+1]--; } for(i=lena-1;!result[i]&&i>0;i--);//处理前端零 for(j=i;j>=0;j--) printf("%d",result[j]); printf("\n"); } return 0; }
#include <cstdio> #include <cmath> void factorial(int n) { int a[10000]; int i,j,c,m=0; a[0]=1; for(i=1;i<=n;i++) { c=0; for(j=0;j<=m;j++)//m表示的是当前数组的位数 { a[j]=a[j]*i+c; c=a[j]/10000;//判断有没有进位 a[j]=a[j]%10000; //保存进位的数 } if(c>0) {m++;a[m]=c;} } printf("%d",a[m]); int w=m*4+log10(a[m])+1;//这里是计算阶乘的总位数 (这里可以不要) for(i=m-1;i>=0;i--) printf("%0.4d",a[i]);//假如当前位置的数没满4位的话,在前补零 printf("\n"); printf("%d",w);//(也可以不要这个输出) } int main() { int m; while(scanf("%d",&m)!=EOF) { factorial(m); } return 0; }