目录
一.高精度介绍
通常,我们只会用string去做关于字符串的题,但是高精度还有另外一个用法,那就是高精度。众所周知,int的范围是-2147483648到2147483647,long long的范围是-2^63到2^63-1。但是有一些题它的范围大于int和long long的范围,这是就需要高精度来帮忙。这是它的定义:
二.模板
高精加:
#include<bits/stdc++.h>
using namespace std;
string a,b;
int s1[255],s2[255],s3[255];
int main(){
cin>>a>>b;
int len1=a.size();
int len2=b.size();
for(int i=0;i<len1;i++){
s1[i]=a[len1-i-1]-'0';
}
for(int i=0;i<len2;i++){
s2[i]=b[len2-i-1]-'0';
}
int maxn=max(len1,len2);
int x=0;
for(int i=0;i<=maxn;i++){
s3[i]=s1[i]+s2[i]+x;
x=s3[i]/10;
s3[i]%=10;
}
if(s3[maxn]>0) maxn++;
for(int i=maxn-1;i>=0;i--) cout<<s3[i];
return 0;
}
高精减:
#include<bits/stdc++.h>
using namespace std;
string a,b;
int s1[114514],s2[114514],s3[114514];
int main(){
cin>>a>>b;
int len1=a.size();
int len2=b.size();
int maxn=max(len1,len2);
if(len1<len2){
cout<<"-";
swap(a,b);
swap(len1,len2);
}
if(len1==len2){
for(int i=0;i<maxn;i++){
if(a[i]<b[i]){
swap(a,b);
swap(len1,len2);
cout<<"-";
break;
}
}
}
for(int i=0;i<len1;i++){
s1[i]=a[len1-i-1]-'0';
}
for(int i=0;i<len2;i++){
s2[i]=b[len2-i-1]-'0';
}
for(int i=0;i<=maxn;i++){
if(s1[i]-s2[i]<0){
s1[i]+=10;
s1[i+1]-=1;
}
s3[i]=s1[i]-s2[i];
}
if(s3[maxn]>0) maxn++;
while(s3[maxn]==0 && maxn>0) maxn--;
for(int i=maxn;i>=0;i--) cout<<s3[i];
return 0;
}
高精乘:
#include<bits/stdc++.h>
using namespace std;
string a,b;
int s1[255],s2[255],s3[1145141];
int main(){
cin>>a>>b;
int len1=a.size();
int len2=b.size();
int maxn=len1+len2;
for(int i=0;i<len1;i++){
s1[i]=a[len1-i-1]-'0';
}
for(int i=0;i<len2;i++){
s2[i]=b[len2-i-1]-'0';
}
for(int i=0;i<=len1;i++){
int x=0;
for(int j=0;j<len2;j++){
s3[i+j]+=s1[i]*s2[j]+x;
x=s3[i+j]/10;
s3[i+j]%=10;
}
s3[i+len2]+=x;
}
if(s3[maxn]>0) maxn++;
while(s3[maxn]==0 && maxn>0) maxn--;
for(int i=maxn;i>=0;i--) cout<<s3[i];
return 0;
}
高精除低精:
#include<bits/stdc++.h>
using namespace std;
int a[114514],sum;
int main(){
string s;cin>>s;
int len=s.size();
for(int i=0;i<len;i++){
sum=sum*10+(s[i]-'0');
a[i]=sum/13;
sum%=13;
}
int pos=0;
while(a[pos]==0 && pos<len-1){
pos++;
}
for(int i=pos;i<len;i++){
cout<<a[i];
}
cout<<endl<<sum;
return 0;
}
高精除高精:
#include<bits/stdc++.h>
#include<cmath>
using namespace std;
int dPZ(int x[],int xLen){
int i=xLen;
while(x[i-1]==0&&i>1){
i--;
}
return i;
}
void printArr(int x[],int xLen){
for(int i=xLen-1;i>=0;i--){
cout<<x[i];
}
cout<<endl;
}
bool cp(int x[],int y[],int xLen,int yLen){
if(xLen<yLen){
return false;
}
if(xLen==yLen){
for(int i=xLen-1;i>=0;i--){
if(x[i]>y[i]){
return true;
}
if(x[i]<y[i]){
return false;
}
}
return true;
}
return true;
}
int sub(int x[],int y[],int z[],int xLen,int yLen){
int zLoc=xLen-yLen;
for(int i=1;i<=yLen;i++){
if(x[xLen-i]>y[yLen-i])
break;
if(x[xLen-i]<y[yLen-i]){
zLoc--;
break;
}
}
if(zLoc<0)
return xLen;
for(int i=zLoc,j=0;i<xLen&&j<yLen;i++,j++){
while(x[i]<y[j]){
x[i+1]--;
x[i]+=10;
}
x[i]-=y[j];
}
z[zLoc]++;
while(x[xLen-1]==0)
xLen--;
if(xLen<=0)
xLen=1;
return xLen;
}
int main(){
char as[301],bs[301];
int a[301]={0},b[301]={0},c[301]={0};
int aLen=0,bLen=0,cLen=1,maxLen=0;
int i;
cin>>as>>bs;
aLen=strlen(as);
bLen=strlen(bs);
for(i=0;i<aLen;i++){
a[i]=as[aLen-1-i]-'0';
}
for(i=0;i<bLen;i++){
b[i]=bs[bLen-1-i]-'0';
}
aLen=dPZ(a,aLen);
bLen=dPZ(b,bLen);
cLen=aLen-bLen+1;
while(cp(a,b,aLen,bLen)){
aLen=sub(a, b, c, aLen, bLen);
}
if(cLen<1){
cLen=1;
}
cLen=dPZ(c,cLen);
printArr(c,cLen);
printArr(a,aLen);
return 0;
}
高精阶乘:
#include<bits/stdc++.h>
using namespace std;
int a[1145141];
int main() {
int sum,pos=1,n,num;
cin>>n;
a[0]=1;
for(int i=2;i<=n;i++){
num=0;
for(int j=0;j<pos;j++){
sum=a[j]*i+num;
a[j]=sum%10;
num=sum/10;
}
while(num){
a[pos]=num%10;
num/=10;
pos++;
}
}
for(int i=pos-1;i>=0;i--){
cout<<a[i];
}
return 0;
}
高精封装(将以上几种用结构体封装起来):
#include<bits/stdc++.h>
using namespace std;
struct node{
int a[10005];
int len;
node(){
memset(a,0,sizeof(a));
len=0;
}
int &operator [](int x){
return a[x];
}
void input(){
string s;cin>>s;
len=s.size();
reverse(s.begin(),s.end());
for(int i=0;i<len;i++){
a[i]=s[i]-'0';
}
}
void print(){
for(int i=len-1;i>=0;i--){
cout<<a[i];
}
cout<<endl;
}
void dao(int l){
len=l;
for(int i=0;i<len;i++){
a[i+1]+=a[i]/10,a[i]%=10;
}
while(a[len-1]==0&&len>0) len--;
}
}x,y,p;
node operator +(node x,node y){
node ans=node();
int mlen=max(x.len,y.len);
for(int i=0;i<mlen;i++){
ans[i]=x[i]+y[i];
}
ans.dao(mlen+1);
return ans;
}
bool cmp(node s,node st){
if(s.len!=st.len) return s.len<st.len;
for(int i=s.len-1;i>=0;i--){
if(s[i]!=st[i]) return s[i]<st[i];
}
return false;
}
node operator -(node x,node y){
node ans=node();
int mlen=max(x.len,y.len);
int flag=cmp(x,y)?0:1;
for(int i=0;i<mlen;i++){
if(flag==1) ans[i]=x[i]-y[i];
else ans[i]=y[i]-x[i];
}
for(int i=0;i<mlen;i++){
while(ans[i]<0) ans[i+1]--,ans[i]+=10;
}
ans.dao(mlen);
if(ans.len==0) ans.len=1,ans[0]=0;
if(cmp(x,y)) cout<<"-";
return ans;
}
node operator *(node x,node y){
node ans=node();
int aans=-1,sum;
for(int i=0;i<y.len;i++){
aans++;
ans.len=aans;
for(int j=0;j<x.len;j++){
ans[ans.len]+=x[j]*y[i];
if(ans[ans.len]>=10){
ans[ans.len+1]+=ans[ans.len]/10;
ans[ans.len]%=10;
}
ans.len++;
}
}
while(ans[ans.len]!=0) ans.len++;
ans.dao(ans.len);
if(ans.len==0) ans.len=1,ans[0]=0;
return ans;
}
node nde(int x){
node ans=node();
do{
ans[ans.len]=x%10;
ans.len++;
}while((x/=10)!=0);
return ans;
}
node operator / (node x,node y){
node u,c;
for(int i=x.len-1;i>=0;i--){
u=u*nde(10)+nde(x[i]);
while(!cmp(u,y)){
u=u-y;
c[i]++;
}
}
c.dao(x.len+1);
if(c.len==0) c.len=1,c[0]=0;
return c;
}
node operator % (node x,node y){
node u,c;
for(int i=x.len-1;i>=0;i--){
u=u*nde(10)+nde(x[i]);
while(!cmp(u,y)){
u=u-y;
c[i]++;
}
}
if(u.len==0) u.len=1,u[0]=0;
return u;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
x.input();
y.input();
p=x+y;
p.print();
p=x-y;
p.print();
p=x*y;
p.print();
p=x/y;
p.print();
p=x%y;
p.print();
return 0;
}