BigNum类封装了所有的功能:
包括输入intput(),输出prin(),还有+-*/
,其中的+-*/还涵盖了左操作数和右操作数正负与大小的所有情况
另外还附带封装了两个数字之间进行比较的辅助函数
里面包含了2个宏定义,RE表示循环和PB表示push_back
求赞,希望转载要带原地址
#include<iostream>
#include<vector>
#include<algorithm>
#define PB push_back
#define RE(i,n) for(int i=0;i<int(n);i++)
using namespace std;
inline char chadd(char a, char b) { return a - '0' + b; }
inline char chminu(char a, char b) { return a - (b - '0'); }
inline char rev(vector<char>&v, int i)
{
return i < v.size() ? v[v.size() - 1 - i] : '0';
}
struct BigNum//可以为负
{
vector<char>V;//如V={1,2,3}表示123
char sign;//正负号
void input()
{
sign = '+'; V.clear(); char c; cin.get(c);
while (c<'0' || c>'9') { if (c == '-')sign = c; cin.get(c); }
while (c >= '0'&&c <= '9') { V.PB(c); cin.get(c); }
}
void prin()
{
if (V[0] == '0')
{
//assert(V.size()==1);
cout << 0; return;
}
if (sign == '-')cout << sign;
//for (auto &x : V)cout << x;
RE(i, V.size())cout << V[i];
}
int AbsCmp(BigNum &ri)//比较两者绝对值
{
int ret(0);
if (V.size() != ri.V.size())ret = V.size() - ri.V.size();
else
{
RE(i, V.size())
{
if (V[i] != ri.V[i])
{
ret = V[i] - ri.V[i]; break;
}
}
}
if (ret)ret /= abs(ret);
return ret;
}
int Cmp(BigNum &ri)//比较大数值的大小
{
int ret(0);
if (sign != ri.sign)ret = (sign == '-' ? -1 : 1);
else
{
ret = (sign == '-' ? -1 : 1)*this->AbsCmp(ri);
}
return ret;
}
//正数与正数相加,符号不管
BigNum EasyPlus(BigNum &ri)
{
int mlen = max(V.size(), ri.V.size());
char accept = '0';
BigNum ret;
RE(i, mlen)
{
char sum = chadd(chadd(rev(V, i), rev(ri.V, i)), accept);
char give = '0';
if (sum > '9')sum -= 10, give = '1';
ret.V.PB(sum); accept = give;
}
if (accept != '0')ret.V.PB(accept);
reverse(ret.V.begin(), ret.V.end());
ret.sign = sign;
return ret;
}
//正数减正数,大数减小数,符号不管
BigNum EasyMinus(BigNum &ri)
{
int mlen = max(V.size(), ri.V.size());
char lose = '0';
BigNum ret;
RE(i, mlen)
{
char rest = chminu(chminu(rev(V, i), rev(ri.V, i)), lose);
char lend = '0';
if (rest < '0')rest += 10, lend = '1';
ret.V.PB(rest); lose = lend;
}
while (ret.V.back() == '0')ret.V.pop_back();
reverse(ret.V.begin(), ret.V.end());
ret.sign = sign;
return ret;
}
BigNum operator-(BigNum &ri)
{
BigNum ret = ri; ret.sign = (ret.sign == '-') ? '+' : '-';
ret = *this + ret;
return ret;
}
BigNum operator+(BigNum &ri)
{
if (sign == ri.sign)return this->EasyPlus(ri);
else
{
BigNum ret;
if (this->AbsCmp(ri) > 0)
{
ret = this->EasyMinus(ri);
ret.sign = sign;
}
else
{
ret = ri.EasyMinus(*this);
ret.sign = ri.sign;
}
return ret;
}
}
BigNum operator*(BigNum &ri)
{
char flag = (sign == ri.sign) ? '+' : '-';
vector<int>R(this->V.size() + ri.V.size() + 10);
RE(i, V.size())
RE(j, ri.V.size())
R[i + j] += (rev(V, i) - '0')*(rev(ri.V, j) - '0');
RE(i, R.size() - 1)
R[i + 1] += R[i] / 10, R[i] %= 10;
while (R.back() == 0)R.pop_back();
reverse(R.begin(), R.end());
BigNum ret; ret.sign = flag;
//for (auto x : R)ret.V.PB(x + '0');
RE(i, R.size())ret.V.PB(R[i] + '0');
return ret;
}
BigNum operator/(BigNum &ri)
{
char flag = (sign == ri.sign) ? '+' : '-';
BigNum ret, le = *this;
int cnt = le.V.size() - ri.V.size();
RE(i, cnt)ri.V.PB('0');
while (1 + cnt--)
{
int shang(0);
while (le.AbsCmp(ri) > 0)++shang, le.EasyMinus(ri);
ret.V.PB(shang + '0');
}
ret.sign = flag;
return ret;
}
};