高精度【大整数运算】
高精度【大整数运算】
注意点
① 高精度有四种,分别是加、减、乘、除,是指运算中某个数的位数高于106。
② 四种运算都是先用string读入,再用vector容器按照从左到右存储低位到高位。
③ 运算的时候 加、减、乘 都是按照从低位到高位的顺序来进行循环计算,相加后的结果也是从左到右由低位到高位存储。
④ 除法是按照从高位到低位来进行运算,相加后的结果从左到右由高位到低位存储(看个人习惯,如果想和加、减、乘,三种运算保持一致也可以)。
加
两个大整数相加A+B (A B都是正整数)
加法按照从低位到高位的顺序进行计算,如果相同的位都存在,就将相同的位上的数字相加,并存储相加之后的个位上的数字,每一次存储的就是相加之后的当前位,而相加的进位未被存储。
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
vector<int> add(vector<int> &A, vector<int> &B) //加上引用&不会重新创建vector容器
{
int t = 0; //t是进位
vector<int> C;
for(int i = 0; i < A.size() || i < B.size(); i ++)
{
int x = 0; //x是当前位相加的结果
x += t; //先加上上一次的进位
if(i < A.size()) x += A[i]; //加上A中当前位的数字
if(i < B.size()) x += B[i]; //加上B中当前位的数字
C.push_back(x % 10); //在C中存储相加后的当前位
t = x/10; //如果当前位置相加的结果x大于10,保存低位,进位置1
}
if(t) C.push_back(t); //如果相加之后结果的位数比两个加数位数多,就要额外保存一下进位
return C;
}
int main()
{
string a,b;
vector<int> A,B,C;
cin >> a >> b;
for(int i=a.size()-1; i>=0; i--) A.push_back(a[i]-'0');
for(int i=b.size()-1; i>=0; i--) B.push_back(b[i]-'0');
C = add(A,B);
for(int i=C.size()-1; i>=0; i--) cout << C[i];
return 0;
}
减
两个大整数相减 A-B (A B都是正整数)
减法同样是按照从低位到高位的顺序进行循环计算,相减的时候先进行判断,使得A > B,然后依次从低位到高位进行计算。
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
vector<int> sub(vector<int> &A, vector<int> B){
vector<int> C;
int t=0; //是否借位,借位t=-1,不借位t=0
for(int i=0; i<A.size(); i++)
{
int x = 0; //保存当前位置计算结果
x += t;
x += A[i];
if(i<B.size()) x -= B[i];
C.push_back((x+10)%10);
t = (x<0) ? -1 : 0;
}
while(C.size()>1 &&C.back() == 0) C.pop_back(); //从高位最先不等于0的位置进行输出
return C;
}
int main()
{
string a,b;
vector<int> A,B,C;
cin >> a >> b;
if(b.size()>a.size() || (a.size()==b.size()&&b>a)){ //如果b>a,输出负号,交换a b的值,保证a是大数
cout << "-";
swap(a,b);
}
for(int i=a.size()-1; i>=0; i--) A.push_back(a[i]-'0');
for(int i=b.size()-1; i>=0; i--) B.push_back(b[i]-'0');
C = sub(A,B);
for(int i=C.size()-1;i>=0;i--)cout << C[i];
return 0;
}
乘
一个大整数乘一个较小值 A*b(A b都是正整数,A是大整数,b在int范围内)
乘法依然是从低位到高位进行运算,每次存储最低位的运算结果。
#include <iostream>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A, int &b)
{
vector<int> C;
long long t=0; //保存进位,开longlong是防止b是int取得最大值,再乘A[i]会超过int取值
for(int i=0; i<A.size(); i++)
{
long long x=0; //保存当前位计算结果
x+=t;
x+=(long long)b*A[i];
C.push_back(x%10);
t = x/10;
}
if(t) C.push_back(t);
return C;
}
int main()
{
string a;
int b;
vector<int> A,C;
cin >> a >> b;
for(int i=a.size()-1; i>=0; i--) A.push_back(a[i]-'0');
if(b==0)
{
cout << 0;
return 0;
}
else C=mul(A,b);
for(int i=C.size()-1; i>=0; i--) cout << C[i];
return 0;
}
除
除法是按照从高位到低位进行计算,每次运算一位计算出结果,将余下的数字放到下一位来进行计算,将被除数所有的位数运算完毕余下的数字就是余数。
#include <iostream>
#include <vector>
using namespace std;
vector<int> div(vector<int> &A, int &b, int &r) //使用引用,得出的结果可以带回
{
vector<int> C;
long long t=0; // 高位除后的余数
for(int i=0; i<A.size(); i++)
{
long long x=0; //开longlong是防止b是int取得最大值,而t刚好等于b-1,t再乘10会爆int
x += t*10;
x += A[i];
C.push_back(x/b);
t=x%b;
}
r=t;
while(C.size()>1 && C.front()==0) C.erase(C.begin()); //删除高位的0
return C;
}
int main()
{
string a;
int b,r;
vector<int> A,C;
cin >> a >> b;
for(int i=0; i<a.size(); i++) A.push_back(a[i]-'0');
if(a=="0"){
cout << 0<<endl<<0;
return 0;
}
else C = div(A,b,r);
for(int i=0;i < C.size();i++) cout << C[i];
cout << endl << r;
return 0;
}

浙公网安备 33010602011771号