高精度-基础练习
高精度加法
数组的每一位相加
#include<bits/stdc++.h> using namespace std; string gaoPlus(string aa,string bb) { int i, t; if (aa.size() < bb.size()){// 两个字符串的长度不一样,要添0 t = aa.size(); for (i = 1; i <= bb.size() - t; i++){ aa = "0" + aa; } }else{ t = bb.size(); for (i = 1; i <= aa.size() - t; i++){ bb = "0" + bb; } } for (i = aa.size() - 1; i >= 0; i--){// 开始加法 aa[i] += bb[i] - '0'; if (aa[i] > '9'){ if (i){ aa[i] -= 10; aa[i-1]++; }else{ aa[i] -= 10; // 最高位进位 999+1=1000 aa = "1" + aa; } } } return aa; }int main(){ string m,n,ans; cin >> m >> n; ans = gaoPlus(m,n); cout<<ans; return 0; }
P1601 A+B Problem(高精)--数组实现
https://www.luogu.com.cn/problem/P1601
#include<bits/stdc++.h> using namespace std; const int N=505; char ca[N],cb[N]; int ia[N],ib[N],sum[N]; /* char数组转int数组 每位数字翻转 a[0]为数组长度 */ void convert(char ca[],int ia[]){ int len=strlen(ca); for(int i=1;i<=len;i++){ ia[i]=ca[len-i]-'0'; } ia[0]=len; } /* 从个位开始每位对齐相加 每位超过10进位 c[0]设置字符长度 */ void add(int a[],int b[],int c[]){ int idx=1,jw=0; while(idx<=a[0] || idx<=b[0]){//从个位开始加 加到位数多的最后一位 int tmp=a[idx]+b[idx]+jw;//计算当前位的值 包含需要进位的 比如 4+8+2=14 此时计算结果为14 jw=tmp/10;//jw 保存当前进位 jw=14/10=1 c[idx]=tmp%10;//保存当前位值 去除进位 c[idx]=14%10=4 idx++;//处理下一位 } while(jw){//jw>0 时 处理进位 c[idx]=jw%10;//保存进位 前面idx++已经为下一位了 jw/=10;//抹去进位 idx++;//处理下一位 } c[0]=idx-1;//上面idx++ 最后一次++没有使用 需要去除 } /* 从后往前输出 */ void print(int c[]){ for(int i=c[0];i>=1;i--){ cout<<c[i]; } } int main(){ cin>>ca>>cb; convert(ca,ia); convert(cb,ib); add(ia,ib,sum); print(sum); return 0; }
高精度减法
#include<bits/stdc++.h> using namespace std; string gaosub(string a1,string b1){ int lena=a1.length(),lenb=b1.length(),lenc, a[250]={},b[250]={},c[250]={}; bool flag = false; if(lena<lenb||lena==lenb&&a1<b1){//默认a1<b1 交换 保证大的在前 swap(lena,lenb); swap(a1,b1); flag=true; } string result; for(int i=0;i<=lena-1;i++){//转换int数组 并数字反转 a[lena-i]=a1[i]-'0'; } for(int i=0;i<=lenb-1;i++){//转换int数组 并数字反转 b[lenb-i]=b1[i]-'0'; } lenc=1; while(lenc<=lena){ if(a[lenc]<b[lenc]){//当前数字不够借位 a[lenc]+=10;//当前+10 a[lenc+1]--;//下一位-1 数字被反转 } c[lenc]=a[lenc]-b[lenc]; lenc++; } while(c[lenc]==0&&lenc>1)lenc--; for(int i=lenc;i>=1;i--) result+=c[i]+'0'; if(flag){ result="-"+result; } return result; } int main(){ string m,n,ans; cin >> m >> n; ans = gaosub(m,n); cout<<ans; return 0; }
P1303 A*B Problem --数组实现
https://www.luogu.com.cn/problem/P1303
#include<bits/stdc++.h> using namespace std; const int N=2005; char ca[N],cb[N]; int a[N],b[N],c[N+N]; /* char数组转int数组 每位数字翻转 a[0]为数组长度 */ void convert(char ca[],int ia[]){ int len=strlen(ca); for(int i=1;i<=len;i++){ ia[i]=ca[len-i]-'0'; } ia[0]=len; } /* 错位相乘 进位 去前导0 设置c[0] 为相乘结果的位数 */ void mut(int a[],int b[],int c[]){ for(int i=1;i<=a[0];i++){ for(int j=1;j<=b[0];j++){ c[i+j-1]+=a[i]*b[j];//错位相乘 i增加1 累加右移一位 } } int i,len=a[0]+b[0];// 两个数相乘 位数不超过两数位数之和 for(i=1;i<len;i++){// 处理进位 c[i+1]+=c[i]/10;//进位 c[i]%=10;//当前位去除进位 } while(c[i]==0 && i>1){//去除前导0 i--; } c[0]=i;//设置相乘的位数 } /* 从后往前输出 */ void print(int c[]){ for(int i=c[0];i>=1;i--){ cout<<c[i]; } } int main(){ cin>>ca>>cb; convert(ca,a); convert(cb,b); mut(a,b,c); print(c); return 0; }
高精度乘法
#include<bits/stdc++.h> using namespace std; string gaomul(string a1,string b1){ int a[200]={},b[200]={},c[500]={}, lena=a1.length(),lenb=b1.length(),lenc,i,j,x; string result; for(i=0;i<=lena-1;i++){//转换int数组 并数字反转 a[lena-i]=a1[i]-'0'; } for(i=0;i<=lenb-1;i++){//转换int数组 并数字反转 b[lenb-i]=b1[i]-'0'; } for(i=1;i<=lena;i++){//逐位相乘 x=0;//进位 for(j=1;j<=lenb;j++){ c[i+j-1]=a[i]*b[j]+x+c[i+j-1]; x=c[i+j-1]/10;//进位往后加 c[i+j-1]%=10;//扣除进位后保留当前位 } c[i+lenb]=x;//和lenb最后一位相加的进位往后加 } lenc=lena+lenb; while(c[lenc]==0&&lenc>1) lenc--; for(i=lenc;i>=1;i--) result+=c[i]+'0'; return result; } int main(){ string m,n,ans; cin >> m >> n; ans = gaomul(m,n); cout<<ans; return 0; }
P2142 高精度减法 --数组实现
https://www.luogu.com.cn/problem/P2142
#include<bits/stdc++.h> using namespace std; const int N=10100; char ca[N],cb[N]; int a[N],b[N],c[N]; void convert(char ca[],int a[]){ int len=strlen(ca); for(int i=1;i<=len;i++){ a[i]=ca[len-i]-'0'; } a[0]=len; } int cmp(int a[],int b[]){ if(a[0]>b[0]) return 1; if(a[0]<b[0]) return -1; for(int i=1;i<a[0];i++){ if(a[i]>b[i]) return 1; if(a[i]<b[i]) return -1; } return 0; } /* 确定两数大小 大-小 从个位开始减 如果减后结果为负数 借位 当前+10 前面一位-1 去前导0 确定结果正负 c[0]赋值数组长度 */ void sub(int a[],int b[],int c[]){ int *tmp1,*tmp2; if(cmp(a,b)>=0){ tmp1=a; tmp2=b; }else{ tmp1=b; tmp2=a; } int i; for(i=1;i<=tmp1[0];i++){ c[i]=tmp1[i]-tmp2[i]+c[i]; if(c[i]<0){ c[i]+=10; c[i+1]-=1; } } i=tmp1[0]; while(c[i]==0 && i>1){ i--; } if(tmp1==b){ c[i]*=-1; } c[0]=i; } void print(int c[]){ for(int i=c[0];i>=1;i--){ cout<<c[i]; } } int main(){ cin>>ca>>cb; convert(ca,a); convert(cb,b); sub(a,b,c); print(c); return 0; }
高精度除法
高精度除以低精度,按位除
#include<bits/stdc++.h> using namespace std; string gaodiv(string a1,int b){ int a[200]={},c[200]={},lena=a1.length(),i,lenc; string result; for(i=0;i<=lena-1;i++){//转换int数组 a[i+1]=a1[i]-'0'; } int x=0;//余数 for (i=1;i<=lena;i++){//按位除 c[i]=(x*10+a[i])/b;//余数*10+当前位数 x=(x*10+a[i])%b; } lenc=1; while(c[lenc]==0&&lenc<lena) lenc++; for(i=lenc;i<=lena;i++) result+=c[i]+'0'; return result; } int main(){ string m,ans; int n; cin >> m >> n; ans = gaodiv(m,n); cout<<ans; return 0; }
P1480 A/B Problem --数组实现
https://www.luogu.com.cn/problem/P1480
#include<bits/stdc++.h> using namespace std; const int N=5005; char ca[N]; int b,a[N],c[N]; /* char数组转int数组 转换时顺序反转 a[0]保存数组长度 */ void convert(char ca[],int a[]){ int len=strlen(ca); for(int i=1;i<=len;i++){ a[i]=ca[len-i]-'0'; } a[0]=len; } /* 高精度/低精度 模拟除法 从高位开始除 商 为0 数组 c[i]=0 和下一位结合继续模拟除以b 商不为0 数组 c[i]=x/b x%b和下一位结合继续模拟除以b 从最高位开始去除前导0 c[0]=i c[0]保存真实c数组-商的长度 */ void div(int a[],int b,int c[]){ long long x=0;int i; for(i=a[0];i>=1;i--){ x=x*10+a[i]; c[i]=x/b; x%=b; } i=a[0]; while(c[i]==0 && i>1){ i--; } c[0]=i; } /* 从高位到低位输出 */ void print(int c[]){ for(int i=c[0];i>=1;i--){ cout<<c[i]; } } int main(){ cin>>ca; cin>>b; convert(ca,a); div(a,b,c); print(c); return 0; }
高精度 低精度取余
类似前面高精度除以低精度
熟练掌握后可尝试做上海计算机学会月赛 2021年4月
巧妙的数
http://iai.sh.cn/problem/422
#include<bits/stdc++.h> using namespace std; int gaoRemainder(string a1,int b){ int a[1000]={},c[1000]={},lena=a1.length(),i,lenc; string result; for(i=0;i<lena;i++){//转换int数组 a[i]=a1[i]-'0'; } int x=0;//余数 for (i=0;i<lena;i++){//按位除 x=(x*10+a[i])%b;//余数参与下次计算 } return x; } int main(){ string m; int n,ans; //输入高精度数m和 int 数 n cin >> m >> n; ans = gaoRemainder(m,n); cout<<ans; return 0; }
高精度除法
高精度除以高精度是用减法模拟除法,对被除数的每一位都减去除数,一直减到当前位置的数字小于除数
#include<bits/stdc++.h> using namespace std; int a[101],b[101],c[101],d,i; //输入 void init(int a[]){ string s; cin>>s; a[0]=s.length(); for(int i=1;i<=a[0];i++){ a[i]=s[a[0]-i]-'0'; } } //输出 void print(int a[]){ if(a[0]==0){ cout<<0<<endl; return; } for(int i = a[0];i>0;i--){ cout<<a[i]; } cout<<endl; return; } //比较 int compare(int a[],int b[]){ int i; if(a[0]>b[0]) return 1; if(a[0]<b[0]) return -1; for(int i=a[0];i>0;i--){ if(a[i]>b[i]) return 1; if(a[i]<b[i]) return -1; } return 0; } void gaosub(int a[],int b[]){ int flag,i; flag = compare(a,b); if(flag==0){ a[0]=0; return; } if(flag==1){ for(int i=1;i<=a[0];i++){ if(a[i]<b[i]){ a[i+1]--; a[i]+=10; } a[i]-=b[i]; } while(a[0]>0&& a[a[0]]==0){ a[0]--; } return; } } void numcpy(int p[],int q[],int det){ for(int i=1;i<=p[0];i++){ q[i+det-1]=p[i]; q[0]=p[0]+det-1; } } void gaodiv(int a[],int b[],int c[]){ int i,tmp[101]; c[0]=a[0]-b[0]+1; for(int i=c[0];i>0;i--){ memset(tmp,0,sizeof(tmp)); numcpy(b,tmp,i); while(compare(a,tmp)>=0){ c[i]++; gaosub(a,tmp); } } while(c[0]>0&&c[c[0]]==0){ c[0]--; } return; } int main(){ memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); init(a); init(b); gaodiv(a,b,c); print(c); print(a); return 0; }
作者:newcode 更多资源请关注纽扣编程微信公众号
从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习