1 高精度
高精度一般用来解决大整数的问题
一般考相加、相减、高精度乘以低精度……
高精加和高精减位数一般 106 位
高精乘的话一般是第一个因数的长度 106,第二个因数是 106
还有一个高精除,也是大数除以小数,求商和余数
是一种较为复杂的模拟
1 高精度加法
(1) 存储
我们需要把大整数的每一位存到数组里面去
一般从个位开始存
因为两个整数相加可能会进位,需要在高位上补一个数,在数组末尾补上一个数是最容易的
(2)运算
是一个模拟人工加法的过程
从个位开始加起,如果大于 10 的话就进位,否则不进位
进位就是 a 数组当前的位数+ b 数组当前的位数 % 10
所以就是 ai + bi +进位
如果这一位不存在直接看成 0
代码
#include<bits/stdc++.h>
using namespace std;
//vector自带size
const int N=1e6+10;
vector<int>add(vector<int> &A,vector<int> &B){//返回结果
vector<int>C;//答案
int t=0;//进位
for(int i=0;i<A.size()||i<B.size();i++){
if(i<A.size())t+=A[i];
if(i<B.size())t+=B[i];
C.push_back(t%10);
t/=10;
}
if(t)C.push_back(1);//如果最高位还有进位就要补上1
return C;
}
int main(){
string a,b;//因为太长了,所以用字符串读进来
vector<int>A,B;//存到vector里面
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');//将数字存进来
auto C=add(A,B);//存一下结果
for(int i=C.size()-1;i>=0;i--)cout<<C[i];//倒着输出
return 0;
}
2 高精度减法
存储是一样的
考虑退位
如果该位减该位大于等于 0 那么就直接减
否则 ai - bi +10
还需要看一下上一位有没有借位
t 表示借位,如果 t 等于 1,表示借过
如果 t 等于 0 的话表示没借过
每次都要减去一个t
a 数组要保证必须是大于 b 数组的
如果 a 小于 b 的话就算 b 减 a,加上一个负号就可以了
有一种前导 0 的问题,需要去掉前导 0
代码
#include<bits/stdc++.h>
using namespace std;
//vector自带size
const int N=1e6+10;
bool cmp(vector<int> &A,vector<int> &B){
if(A.size()!=B.size())return A.size()>B.size();
for(int i=A.size()-1;i>=0;i--){
if(A[i]!=B[i])
return A[i]>B[i];
}
return true;
}
vector<int>sub(vector<int> &A,vector<int> &B){//返回结果
vector<int>C;//答案
for(int i=0,t=0;i<A.size();i++){
t=A[i]-t;
if(i<B.size())t-=B[i];
C.push_back((t+10)%10);
if(t<0)t=1;
else t=0;
}
while(C.size()>1&&C.back()==0){//删除前导0
C.pop_back();
}
return C;
}
int main(){
string a,b;//因为太长了,所以用字符串读进来
vector<int>A,B;//存到vector里面
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');//将数字存进来
if(cmp(A,B)){
auto C=sub(A,B);
for(int i=C.size()-1;i>=0;i--)cout<<C[i];//倒着输出
}else{
auto C=sub(B,A);
cout<<'-';
for(int i=C.size()-1;i>=0;i--)cout<<C[i];//倒着输出
}
return 0;
}
3 高精度乘法
高精乘就是大数乘小数
如一个非常大的数乘小数
得数就是a[i]*b[i]%10
到下一位我们还需要加上一个进位,进位是a*b/10
我们需要把 b 看作一个整体
所以呢综合来讲,就是(a[i]*b/10)+(a[i]*b%10)
举个例子:
123 * 12
先算a[0]*12
,a[0]
等于 3,所以结果等于 3*12%10
等于 6
进位就等于3*12/10
等于 3
下一位的结果就是2*12
等于2*12%10
等于 4,再加上前一位的进位 3,所以为 7
代码
#include<bits/stdc++.h>
using namespace std;
vector<int>mul(vector<int>&A,int b){
vector<int>C;
int t=0;//进位
for(int i=0;i<A.size()||t;i++){//如果i没有循环完或进位没出理完就继续做
if(i<A.size())t+=A[i]*b;//A没遍历完就可以乘
C.push_back(t%10);//取出个位
t/=10;//进位
}
while(C.size()>1&&C.back()==0)C.pop_back();
return C;
}
int main(){
string a;
int b;
cin>>a>>b;
vector<int>A;
for(int i=a.size()-1;i>=0;i--){
A.push_back(a[i]-'0');
}
auto C=mul(A,b);
for(int i=C.size()-1;i>=0;i--)cout<<C[i];
return 0;
}
tql