高精度加法与高精度减法的总体思路都是先将数字倒序存入数组中,计算出结果之后去除多余的前置零倒序输出。下文的加法和减法代码我为了少开两个数组和避免倒序写的比较抽象
高精度加法
核心代码
c[i]=a[i]+b[i];
c[i+1]+=c/10;
c[i]%=10;
#include <bits/stdc++.h>
using namespace std;
int c[501];
void add(string &a,string &b){
unsigned int la=a.size();
unsigned int lb=b.size();
unsigned int lc=max(la,lb);
c[0]=0;
for(int i=0;i<la;i++)
c[lc-i]=a[la-i-1]-'0';
for(int i=0;i<lb;i++){
c[lc - i] += b[lb - i-1] - '0';
c[lc - i - 1] += c[lc - i] / 10;
c[lc - i] %=10;
}
int i=0;
while(c[i]==0 and i<=lc)
i++;
for(int j=i;j<=lc;j++)
cout << c[j];
if (i>lc)
cout << 0;
}
int main() {
string a,b;
cin >> a;
cin >> b;
add(a,b);
return 0;
}
高精度减法
核心代码
for(int i=1;i<=lb;i++){
if(a[la-i]<b[lb-i]+flag){
c[la-i]=a[la-i]-b[lb-i]+10-flag;
flag=1;
}
else{
c[la-i]=a[la-i]-b[lb-i]-flag;
flag=0;
}
}
#include <bits/stdc++.h>
using namespace std;
int c[10086];
void sub(string &a,string &b){
unsigned int la=a.size();
unsigned int lb=b.size();
if (la<lb or (la==lb and a<b)){
swap(a,b);
swap(la,lb);
cout << '-';
}
int flag=0;
for(int i=1;i<=la;i++)
c[la-i]=a[la-i]-'0';
for(int i=1;i<=lb;i++){
if(a[la-i]<b[lb-i]+flag){
c[la-i]=a[la-i]-b[lb-i]+10-flag;
flag=1;
}
else{
c[la-i]=a[la-i]-b[lb-i]-flag;
flag=0;
}
}
for(int i=la-lb;i>0;i--){
if(a[i-1]<'0'+flag)
c[i-1]=a[i-1]-'0'+10-flag;
else{
c[i-1]=a[i-1]-flag-'0';
break;
}
}
int i=0;
while (i<la and c[i]==0)
i++;
for(int j=i;j<la;j++)
cout << c[j];
if(i==la)
cout << 0;
}
int main() {
string a,b;
cin >> a;
cin >> b;
sub(a,b);
return 0;
}
高精度乘法
高精度乘法的基本思路是按位乘以后使用高精度加法
核心代码
c[i+j-1]+=Na[i]*Nb[j];
#include <bits/stdc++.h>
using namespace std;
int c[5000],Na[2001],Nb[2001];
void mult(string &a,string &b){
Na[0]=(int)a.size();
Nb[0]=(int)b.size();
for(int i=1;i<=Na[0];i++)
Na[i]=a[Na[0]-i]-'0';
for(int i=1;i<=Nb[0];i++)
Nb[i]=b[Nb[0]-i]-'0';
for(int i=1;i<=Na[0];i++){
for(int j=1;j<=Nb[0];j++){
c[i+j-1]+=Na[i]*Nb[j];
}
}
int len=Na[0]+Nb[0];
for(int i=1;i<=len;i++){
c[i+1]+=c[i]/10;
c[i]%=10;
}
while(c[len]==0 && len>1)
len--;
for(int i=len;i>=1;i--)
cout << c[i];
}
int main() {
string a,b;
cin >> a;
cin >> b;
mult(a,b);
return 0;
}
高精度除法
高精度除以低精度
思路是试商,直接模拟便可
#include <bits/stdc++.h>
using namespace std;
int Na[5002],Nb[5002],c[5002];
void div1(string &a,long long b){
int la=(int)a.size();
long long val=0;
for(int i=0;i<la;i++){
val=val*10+a[i]-'0';
c[i]=val/b;
val%=b;
}
int i=0;
while(i<la && c[i]==0){
i++;
}
for(int j=0;j<la+1;j++)
cout << c[j];
if(i==la)
cout << 0;
}
int main() {
int b;
string a;
cin >> a;
cin >> b;
div1(a,b);
return 0;
}
高精度除以高精度
高精度除以高精度的思路是用高精度减法试商,代码就稍微复杂一点了,尤其是在下标上容易出错
#include <bits/stdc++.h>
using namespace std;
int Na[5002],Nb[5002],c[5002],temp[5002];
//比较函数,判断是否可以做减法
bool compare(int a[],int b[]){
if(a[0]>b[0])
return true;
if(a[0]<b[0])
return false;
for(int i=0;i<a[0];i++)
if(a[a[0]-i]<b[b[0]-i])
return false;
else if(a[a[0]-i]>b[b[0]-i])
return true;
return true;
}
//将除数右移pos位拷贝到temp数组
void copyto(int pos){
memset(temp,0,sizeof temp);
temp[0]=Nb[0]+pos;
for(int i=1;i<=Nb[0];i++)
temp[i+pos]=Nb[i];
}
//进行高精度减法
void sub(){
int flag=0;
for(int i=1;i<=Na[0];i++){
if(Na[i]<flag+temp[i]){
Na[i]-=flag+temp[i]-10;
flag=1;
}
else{
Na[i]-=flag+temp[i];
flag=0;
}
}
int i=Na[0];
while(i>0 && Na[i]==0)
i--;
Na[0]=i;
}
void div2(string &a,string &b){
Na[0]=(int)a.size();
Nb[0]=(int)b.size();
memset(c,0,sizeof c);
c[0]=Na[0]-Nb[0]+1;
for(int i=1;i<=Na[0];i++)
Na[i]=a[Na[0]-i]-'0';
for(int i=1;i<=Nb[0];i++)
Nb[i]=b[Nb[0]-i]-'0';
for(int i=Na[0]-Nb[0]+1;i>0;i--){
copyto(i-1);
while(compare(Na,temp)){
sub();
c[i]++;
}
}
int i=c[0];
while(i>0 && c[i]==0)
i--;
for(int j=i;j>=1;j--)
cout << c[j];
if(i<=0)
cout << 0;
}
int main() {
string a,b;
cin >> a;
cin >> b;
div2(a,b);
return 0;
}