比赛中常常会遇到数据范围大于long long int的情况,这时候需要使用高精度运算,为了在比赛中顺利解决高精度问题,我写出了如下的高精度运算模板,包含高精度加法、乘法、大小比较,高精度输入、输出,并且使用重载运算符,可以完美代替long long int/int类型
<p>#define MAXN 1000 //数字长度 #define SYS 10 //进制</p><p>/* 双高精度ACM模板,By:qpswwww(ZYK) 保存方式: 低位->高位, s[] -> 1 2 3 4 eg:1013->[3][1][0][1] */</p><p>struct Hugeint //高精度 { int s[MAXN]; int size; //数字大小 int sign; //符号,1为正,-1为负,0为零 Hugeint operator + (Hugeint b) //高精度加法 { int i,j; Hugeint out; out.s[0]=0; out.size=size; if(b.size>size) out.size=b.size; for(i=1;i<=out.size;i++) out.s[i]=s[i]; for(i=1;i<=out.size;i++) out.s[i]+=b.s[i]; for(i=1;i<=size;i++) { if(out.s[i-1]/SYS>0) out.s[i]+=out.s[i-1]/SYS; out.s[i-1]%=SYS; } if(out.s[size]/SYS>0) { out.size++; out.s[size]=out.s[size-1]/SYS; out.s[size-1]%=SYS; } return out; } Hugeint operator*(Hugeint b) //高精度乘法 { int i,j; Hugeint out; memset(out.s,0,sizeof(out.s)); out.sign=sign*b.sign; for(i=1;i<=size;i++) { for(j=1;j<=b.size;j++) { out.s[i+j-1]+=(s[i]*b.s[j]); } } for(i=1;i<MAXN;i++) { if(out.s[i-1]/SYS>0) out.s[i]+=out.s[i-1]/SYS; out.s[i-1]%=SYS; } for(i=MAXN-1;i>=1;i--) if(out.s[i]) break; out.size=i; return out; } bool operator>(Hugeint b) //高精度大于 { int i,j; if(sign==b.sign&&sign==-1) { if(size<b.size) return 1; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 0; if(s[i]<b.s[i]) return 1; } } else { if(sign>b.sign) return 1; if(size>b.size) return 1; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 1; if(s[i]<b.s[i]) return 0; } } return 0; } bool operator<(Hugeint b) //高精度小于 { int i,j; if(sign==b.sign&&sign==-1) { if(size<b.size) return 0; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 1; if(s[i]<b.s[i]) return 0; } } else { if(sign>b.sign) return 0; if(size>b.size) return 0; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 0; if(s[i]<b.s[i]) return 1; } } return 0; } void print() //输出 { int i,flag=0; if(sign==-1) printf("-"); else if(sign==0) { printf("0"); return; } for(i=size;i>=1;i--) { if(flag) printf("%d",s[i]); else if(s[i]) printf("%d",s[i]),flag=1; } } void scan() //输入 { memset(s,0,sizeof(s)); int i=0,j; char in[MAXN]; scanf("%s",in); if(in[0]=='-') sign=-1,i++; else if(in[0]=='0') sign=0; else sign=1; size=strlen(in)-i; for(j=size;j>0;i++,j--) s[j]=in[i]-'0'; } }; </p>
例题
给出数字a,b,求a*b的结果
Sample Input
20 40
Sample Output
800
Hint
0<a,b<10^1000
样例程序
#include <stdio.h> #include <string.h> #define MAXN 1000 #define SYS 10 //进制 /* 双高精度ACM模板,By:qpswwww(ZYK) 保存方式: 低位->高位, s[] -> 1 2 3 4 eg:1013->[3][1][0][1] */ struct Hugeint //高精度 { int s[MAXN]; int size; //数字大小 int sign; //符号,1为正,-1为负,0为零 Hugeint operator + (Hugeint b) //高精度加法 { int i,j; Hugeint out; out.s[0]=0; out.size=size; if(b.size>size) out.size=b.size; for(i=1;i<=out.size;i++) out.s[i]=s[i]; for(i=1;i<=out.size;i++) out.s[i]+=b.s[i]; for(i=1;i<=size;i++) { if(out.s[i-1]/SYS>0) out.s[i]+=out.s[i-1]/SYS; out.s[i-1]%=SYS; } if(out.s[size]/SYS>0) { out.size++; out.s[size]=out.s[size-1]/SYS; out.s[size-1]%=SYS; } return out; } Hugeint operator*(Hugeint b) //高精度乘法 { int i,j; Hugeint out; memset(out.s,0,sizeof(out.s)); out.sign=sign*b.sign; for(i=1;i<=size;i++) { for(j=1;j<=b.size;j++) { out.s[i+j-1]+=(s[i]*b.s[j]); } } for(i=1;i<MAXN;i++) { if(out.s[i-1]/SYS>0) out.s[i]+=out.s[i-1]/SYS; out.s[i-1]%=SYS; } for(i=MAXN-1;i>=1;i--) if(out.s[i]) break; out.size=i; return out; } bool operator>(Hugeint b) //高精度大于 { int i,j; if(sign==b.sign&&sign==-1) { if(size<b.size) return 1; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 0; if(s[i]<b.s[i]) return 1; } } else { if(sign>b.sign) return 1; if(size>b.size) return 1; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 1; if(s[i]<b.s[i]) return 0; } } return 0; } bool operator<(Hugeint b) //高精度小于 { int i,j; if(sign==b.sign&&sign==-1) { if(size<b.size) return 0; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 1; if(s[i]<b.s[i]) return 0; } } else { if(sign>b.sign) return 0; if(size>b.size) return 0; for(i=size;i>=1;i--) { if(s[i]>b.s[i]) return 0; if(s[i]<b.s[i]) return 1; } } return 0; } void print() //输出 { int i,flag=0; if(sign==-1) printf("-"); else if(sign==0) { printf("0"); return; } for(i=size;i>=1;i--) { if(flag) printf("%d",s[i]); else if(s[i]) printf("%d",s[i]),flag=1; } } void scan() //输入 { memset(s,0,sizeof(s)); int i=0,j; char in[MAXN]; scanf("%s",in); if(in[0]=='-') sign=-1,i++; else if(in[0]=='0') sign=0; else sign=1; size=strlen(in)-i; for(j=size;j>0;i++,j--) s[j]=in[i]-'0'; } }; int main() { Hugeint a,b,c; a.scan(); b.scan(); c=a*b; c.print(); return 0; }
模板可能有误或存在不足,希望各位大神不吝指教,感激不尽!