高精度计算
本文中大数指长度为10e6范围类的数,小数 <= 10000
总体思路:将大数存到数组中进行计算,由于考虑到最高位的进位会添加数位,所以选择将数逆序存到数组中,即下标小的存低位,下标大的存高位
大数 + 大数
模拟手算加法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> add(vector<int> &A,vector<int> &B){
vector<int> res;
int t = 0; //t表示进位
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];
res.push_back(t % 10);
t /= 10;
}
if(t) res.push_back(1);
return res;
}
int main()
{
string a,b;
vector<int> A,B;
cin >> a >> b;
for(int i = a.size() - 1;i >= 0;i --) A.push_back(a[i] - '0'); //将a,b两个数逆序存储到数组中
for(int i = b.size() - 1;i >= 0;i --) B.push_back(b[i] - '0');
vector<int> C = add(A,B);
for(int i = C.size() - 1;i >= 0;i --)
printf("%d",C[i]);
return 0;
}
大数 - 大数
模拟手算减法,注意计算之前判断两数的大小,若A > B则计算A - B,若A < B则计算B - A最后再加个-,还要
记得将最后结果的前导零都删除掉
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(vector<int> &A,vector<int> &B){
if(A.size() != B.size()) return A.size() > B.size();
else{
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> res;
int t = 0;
for(int i = 0;i < A.size();i ++){
int x = A[i] -t;
if(i < B.size()) x -= B[i];
res.push_back((x + 10) % 10);
if(x >= 0) t = 0;
else t = 1;
}
while(res.size() > 1 && res.back() == 0) res.pop_back();
return res;
}
int main(){
string a,b;
vector<int> A,B;
cin >> a >> b;
for(int i = a.size() - 1;i >= 0;i --) A.push_back(a[i] - '0'); //将a,b两个数逆序存储到数组中
for(int i = b.size() - 1;i >= 0;i --) B.push_back(b[i] - '0');
vector<int> res;
if(!cmp(A,B)){
printf("-");
res = sub(B,A);
}else{
res = sub(A,B);
}
for(int i = res.size() - 1;i >= 0;i --) printf("%d",res[i]);
return 0;
}
大数 x 小数
这里与手算乘法有所不用,我们是将大数的每一项分别与小数整体相乘
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A,int b){
vector<int> res;
int t = 0; //t表示进位
for(int i = 0;i < A.size();i ++){
res.push_back((A[i] * b + t) % 10);
t = (A[i] * b + t) / 10;
}
if(t) res.push_back(t);
return res;
}
int main()
{
string a;
int b;
vector<int> A;
cin >> a >> b;
if(b == 0){
cout << 0;
return 0;
}
for(int i = a.size() - 1;i >= 0;i --) A.push_back(a[i] - '0'); //将a,b两个数逆序存储到数组中
vector<int> C = mul(A,b);
for(int i = C.size() - 1;i >= 0;i --)
printf("%d",C[i]);
return 0;
}
大数 / 小数
模拟手算除法,这里也要注意处理前导零的问题
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> divide(vector<int> &A,int b,int &t){
vector<int> res;
t = 0;
for(int i = A.size()- 1;i >= 0;i --){
int a = t * 10 + A[i];
res.push_back(a / b);
t = a % b;
}
reverse(res.begin(),res.end());
while(res.size() > 1 && res.back() == 0) res.pop_back();
return res;
}
int main()
{
string a;
int b;
vector<int> A;
cin >> a >> b;
int t;
for(int i = a.size() -1;i >= 0;i --) A.push_back(a[i] - '0'); //将a,b两个数逆序存储到数组中
vector<int> C = divide(A,b,t);
for(int i = C.size() - 1;i >= 0;i --){
printf("%d",C[i]);
}
cout << endl << t;
return 0;
}