使用结构体实现高精度加减乘除运算,但是除法运算的复杂度较高,(其实乘法也是),更优的方法涉及到数学方法,在此没有采用,参考《算法竞赛入门经典第二版》
解释写在代码中
加减乘除均为模拟列竖式的过程
#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
using namespace std;
struct BigInteger{
static const int BASE=1e8;
static const int WIDTH=8; //下面的vector<int> s中,每个s[i]储存的位数,现在是8位,所以BASE=10^8
vector<int> s;
//初始化
BigInteger(long long num=0) {*this=num;} //构造函数,用于初始化BigInteger变量,默认值为0
//赋值
BigInteger operator = (long long num){ //赋值操作:long long to BigInteger
s.clear(); //s中,数的低位保存在前,高位保存在后
do{
s.push_back(num%BASE);
num/=BASE;
}while(num>0);
return *this;
}
BigInteger operator = (const string& str){
s.clear();
int x,len=(str.length()-1)/WIDTH+1; //len:vector保存的元素数量
for(int i=0;i<len;i++){
int endd=str.length()-i*WIDTH;
int start=max(0,endd-WIDTH);
sscanf(str.substr(start,endd-start).c_str(),"%d",&x); //从start开始,截取endd-start长度的字符串
s.push_back(x);
}
return *this;
}
//比较(实现小于,等于,也就实现了全部比较)
bool operator < (const BigInteger& b) const {
if(s.size()!=b.s.size()) return s.size()<b.s.size();
for(int i=s.size()-1;i>=0;i--)
if(s[i]!=b.s[i]) return s[i]<b.s[i];
return false;
}
bool operator == (const BigInteger&b) const {
return s==b.s;
}
//加减乘除运算
BigInteger operator + (const BigInteger& b) const{
BigInteger c;
c.s.clear();
for(int i=0,g=0;;i++){
if(g==0 && i>=s.size() && i>=b.s.size()) break;
int x=g;
if(i<s.size()) x+=s[i];
if(i<b.s.size()) x+=b.s[i];
c.s.push_back(x%BASE);
g=x/BASE;
}
return c;
}
BigInteger operator - (const BigInteger& b) const { //只适用于结果大于等于0的情况(即若要计算a-b,则需要保证a>=b)
BigInteger c;
c.s.clear();
int g = 0; // 借位
for (int i = 0; ; i++) {
if (i >= s.size()) break;
int x = g;
x += s[i];
if(i<b.s.size()) x -= b.s[i];
if (x < 0) {
x += BASE;
g = -1;
} else {
g = 0;
}
c.s.push_back(x);
}
// Remove leading zeros
while (c.s.size() > 1 && c.s.back() == 0) {
c.s.pop_back();
}
return c;
}
BigInteger operator * (const BigInteger& b) const {
BigInteger c;
c.s.resize(s.size() + b.s.size(), 0); //a*b乘法结果的位数最多是:a的位数+b的位数,将每一个s中的元素初始化为0
for (int i = 0; i < s.size(); i++) {
for (int j = 0; j < b.s.size(); j++) {
long long mul = (long long)s[i] * b.s[j] + c.s[i + j];
c.s[i + j] = mul % BASE;
c.s[i + j + 1] += mul / BASE;
}
}
// remove leading zeros
while (c.s.size() > 1 && c.s.back() == 0) {
c.s.pop_back();
}
return c;
}
BigInteger operator / (const BigInteger& b) const {
BigInteger c;
c.s.resize(s.size(), 0);
BigInteger remainder;
for (int i = s.size() - 1; i >= 0; i--) {
remainder.s.insert(remainder.s.begin(), s[i]);
int quotient = 0;
while (b<remainder || b==remainder) {
remainder = remainder - b;
quotient++;
}
c.s[i] = quotient;
}
// Remove leading zeros
while (c.s.size() > 1 && c.s.back() == 0) {
c.s.pop_back();
}
return c;
}
};
ostream& operator << (ostream& out,const BigInteger& x){
out<<x.s.back();
for(int i=x.s.size()-2;i>=0;i--){
char buf[20];
sprintf(buf,"%08d",x.s[i]);
for(int j=0;j<strlen(buf);j++) out<<buf[j];
}
return out;
}
istream& operator >>(istream& in,BigInteger& x) {
string s;
if(!(in>>s)) return in;
x=s;
return in;
}
int main()
{
BigInteger a,b;
while(cin>>a>>b){
cout<<a+b<<"\n";
cout<<a-b<<"\n";
cout<<a*b<<"\n";
cout<<a/b<<"\n";
}
return 0;
}