大数四则运算类
#include "stdlib.h"
#include <iostream>
#include <assert.h>
#include <time.h>
#include <vector>
using namespace std;
#define BI_NEG 0
#define BI_POS 1
class big_int;
const big_int operator+(const big_int &, const big_int &);
const big_int operator-(const big_int &, const big_int &);
const big_int operator*(const big_int &, const big_int &);
const big_int operator/(const big_int &, const big_int &);
const big_int operator%(const big_int &, const big_int &);
bool operator<(const big_int &, const big_int &);
bool operator<=(const big_int &, const big_int &);
bool operator==(const big_int &, const big_int &);
bool operator>=(const big_int &, const big_int &);
bool operator>(const big_int &, const big_int &);
ostream& operator<<(ostream& _OStr, const big_int& rhs);
const big_int bipow(const big_int &, const int);
const big_int bifact(int);
class big_int
{
private:
static const unsigned base = 10000;
int sign;
vector<unsigned> number;
public:
big_int(){number.push_back(0);};
big_int(const char *);
big_int(const big_int &bi):number(bi.number),sign(bi.sign){};
big_int(int);
big_int(long long);
int get_sign(){return sign;};
big_int& operator+=(const big_int&);
big_int& operator-=(const big_int&);
big_int& operator*=(const big_int&);
big_int& operator/=(const big_int&);
big_int& operator%=(const big_int&);
void output();
private:
friend bool operator<(const big_int &, const big_int &);
friend ostream& operator<<(ostream&, const big_int&);
//number加上rhs的number
void add(const vector<unsigned> &);
//两个相减,结果放回number中
void minus(const vector<unsigned> &, const vector<unsigned> &);
void minus(const vector<unsigned> &);
static bool less(const vector<unsigned> &, const vector<unsigned> &);
};
big_int::big_int(int n)
{
if(n < 0) sign = BI_NEG; else sign = BI_POS;
if(n == 0) {number.push_back(0);}
else
{
if(n < 0) n = -n;
while(n != 0)
{
number.push_back(n % base);
n /= base;
}
}
}
big_int::big_int(long long n)
{
if(n < 0) sign = BI_NEG; else sign = BI_POS;
if(n == 0) {number.push_back(0);}
else
{
if(n < 0) n = -n;
while(n != 0)
{
number.push_back((int)(n % base));
n /= base;
}
}
}
big_int::big_int(const char * str)
{
int len = strlen(str);
assert(len > 0);
int from = 0;
int temp = 0;
if(str[0] == '-'){sign = BI_NEG; from = 1;}
else{sign = BI_POS;}
int idx = len - 1;
int de = 0;
int times = 1;
while(idx - de >= from)
{
if(de % 4 == 0)
{
times = 1;
}
temp += (times * (str[idx - de] - '0'));
times *= 10;
if(de % 4 == 3)
{
number.push_back(temp);
temp = 0;
}
++de;
}
if(temp != 0) number.push_back(temp);
int i = number.size() - 1;
while(i > 0 && number[i] == 0){number.pop_back(); --i;}
if(number.size() == 0) {number.push_back(0);sign = BI_POS;}
}
void big_int::output()
{
if(sign == BI_NEG) cout << '-';
cout << number[number.size() - 1];
for(int i = number.size() - 2; i >= 0; --i)
{
cout << number[i] / 1000 << (number[i] % 1000) / 100
<< (number[i] % 100) / 10 << number[i] % 10;
}
}
bool big_int::less(const vector<unsigned> &lhs, const vector<unsigned> &rhs)
{
if(lhs.size() < rhs.size()) return true;
else if(rhs.size() < lhs.size()) return false;
else
{
for(int i = lhs.size() - 1; i >= 0; --i)
{
if(lhs[i] < rhs[i]) return true;
else if(rhs[i] < lhs[i]) return false;
}
}
return false;
}
void big_int::add(const vector<unsigned> &rhs)
{
int nleft = number.size();
int nright = rhs.size();
int i = 0;
unsigned c = 0;
unsigned temp = 0;
while(nleft < nright){ number.push_back(0); ++nleft;}
while(i < nright)
{
temp = number[i] + rhs[i] + c;
number[i] = temp % base;
c = temp / base;
++i;
}
while(i < nleft && c != 0)
{
temp = number[i] + c;
number[i] = temp % base;
c = temp / base;
++i;
}
if(c != 0) number.push_back(c);
}
void big_int::minus(const vector<unsigned> &lhs, const vector<unsigned> &rhs)
{
vector<unsigned> res;
int nleft = lhs.size();
int nright = rhs.size();
int i = 0;
unsigned c = 0;
unsigned temp = 0;
res.resize(nleft);
for(i = nleft -1; i >= 0; --i) res[i] = 0;
i = 0;
while(i < nright)
{
temp = lhs[i] + base - rhs[i] - c;
res[i] = temp % base;
c = temp / base;
c = (c == 1 ? 0 : 1);
++i;
}
while(i < nleft)
{
temp = lhs[i] + base - c;
res[i] = temp % base;
c = temp / base;
c = (c == 1 ? 0 : 1);
++i;
}
i = nleft - 1;
while(i > 0 && res[i] == 0){ res.pop_back(); --i;}
number = res;
}
void big_int::minus(const vector<unsigned> &rhs)
{
int nleft = number.size();
int nright = rhs.size();
int i = 0;
unsigned c = 0;
unsigned temp = 0;
while(i < nright)
{
temp = number[i] + base - rhs[i] - c;
number[i] = temp % base;
c = temp / base;
c = (c == 1 ? 0 : 1);
++i;
}
while(i < nleft)
{
temp = number[i] + base - c;
number[i] = temp % base;
c = temp / base;
c = (c == 1 ? 0 : 1);
++i;
}
i = nleft - 1;
while(i > 0 && number[i] == 0){number.pop_back(); --i;}
}
big_int& big_int::operator+=(const big_int &rhs)
{
if(rhs.sign == sign){ add(rhs.number);}//同号相加
else if(less(number, rhs.number))//绝对值较小
{
sign = rhs.sign;
minus(rhs.number,number);
}
else
{
minus(rhs.number);
}
return *this;
}
big_int& big_int::operator-=(const big_int &rhs)
{
if(rhs.sign != sign){ add(rhs.number);}//异号则相加
else if(less(number, rhs.number))
{
sign = sign ^ 1;
minus(rhs.number, number);
}
else
{
minus(rhs.number);
}
return *this;
}
big_int& big_int::operator*=(const big_int &rhs)
{
if(sign != rhs.sign) sign = BI_NEG; else sign = BI_POS;
int nleft = number.size();
int nright = rhs.number.size();
int i,j,c,temp,idx;
int maxlen = nleft + nright + 1;
vector<unsigned> res;
res.resize(maxlen);
for(i = 0; i < maxlen; ++i){ res[i] = 0;};
for(i = 0; i < nright; ++i)
{
c = 0; temp = 0; idx = i;
for(j = 0; j < nleft; ++j)
{
temp = number[j] * rhs.number[i] + res[idx] + c;
res[idx] = temp % base;
c = temp / base;
++idx;
}
while(c != 0)
{
temp = res[idx] + c;
res[idx] = temp % base;
c = temp / base;
++idx;
}
}
i = res.size() - 1;
while(i > 0 && res[i] == 0){res.pop_back(); --i;}
number = res;
return *this;
}
big_int& big_int::operator/=(const big_int &rhs)
{
int nleft = number.size();
int nright = rhs.number.size();
int i, temp;
if(sign != rhs.sign) sign = BI_NEG; else sign = BI_POS;
assert(!(nright == 1 && rhs.number[0] == 0));//除数不为0
if(less(number,rhs.number))
{
number.resize(0); number.push_back(0);sign = BI_POS; return *this;
}
vector<unsigned> diver;
vector<unsigned> mid;
vector<unsigned> res;
diver.resize(nright + 1);
mid.resize(nright + 1);
for(i = 0; i <= nright; ++i) diver[i] = 0;
res.resize(nleft - nright + 1);
for(i = 0; i <= nleft - nright; ++i) res[i] = 0;
int ires = nleft - nright;
int idx = nleft - nright + 1;
for(i = 0; i < nright - 1; ++i)
{
diver[i] = number[idx + i];
}
--idx;
int max_idx_diver = diver.size() - 1;
int max_idx_right = rhs.number.size() - 1;
int temp_res;
int c, temp2;
for(; idx >= 0; --idx)
{
for(i = max_idx_diver; i > 0; --i) diver[i] = diver[i-1];
diver[0] = number[idx];
temp = diver[max_idx_diver] * base + diver[max_idx_diver - 1];
temp_res = temp / rhs.number[max_idx_right];
while(temp_res >= 0)
{
c = 0;
for(i = 0; i <= max_idx_right; ++i)
{
temp2 = rhs.number[i] * temp_res + c;
mid[i] = temp2 % base;
c = temp2 / base;
}
mid[max_idx_diver] = c;
if(less(diver,mid)) --temp_res;
else break;
}
c = 0;
for(i = 0; i <= max_idx_right; ++i)
{
temp2 = rhs.number[i] * temp_res + c;
mid[i] = temp2 % base;
c = temp2 / base;
}
mid[max_idx_diver] = c;
c = 0;
for(i = 0; i <= max_idx_diver; ++i)
{
temp2 = diver[i] + base - mid[i] - c;
diver[i] = temp2 % base;
c = temp2 / base;
c = c ^ 1;
}
res[idx] = temp_res;
}
i = res.size() - 1;
while(i > 0 && res[i] == 0){res.pop_back(); --i;}
number = res;
return *this;
}
big_int& big_int::operator%=(const big_int& rhs)
{
int nleft = number.size();
int nright = number.size();
assert(!(nright == 1 && rhs.number[0] == 0));
//符号不变
if(less(number,rhs.number)) return *this;
big_int bi1(*this);
bi1 /= rhs;
bi1 *= rhs;
big_int bi2(*this);
bi2 -= bi1;
number = bi2.number;
if(number.size() == 1 && number[0] == 0) sign = BI_POS;
return *this;
}
//////////////////////////////////////////////////////////////////////////////
const big_int operator+(const big_int &lhs, const big_int &rhs)
{
big_int res(lhs);
res += rhs;
return res;
}
const big_int operator-(const big_int &lhs, const big_int &rhs)
{
big_int res(lhs);
res -= rhs;
return res;
}
const big_int operator*(const big_int &lhs, const big_int &rhs)
{
big_int res(lhs);
res *= rhs;
return res;
}
const big_int operator/(const big_int &lhs, const big_int &rhs)
{
big_int res(lhs);
res /= rhs;
return res;
}
const big_int operator%(const big_int &lhs, const big_int &rhs)
{
big_int res(lhs);
res %= rhs;
return res;
}
bool operator<(const big_int &lhs, const big_int &rhs)
{
if(lhs.sign < rhs.sign) return true;
else if(rhs.sign < lhs.sign) return false;
else if(lhs.sign == BI_POS) return big_int::less(lhs.number,rhs.number);
else return big_int::less(rhs.number, lhs.number);
}
bool operator<=(const big_int &lhs, const big_int &rhs)
{
return !(rhs < lhs);
}
bool operator==(const big_int &lhs, const big_int &rhs)
{
return !(rhs < lhs) && !(lhs < rhs);
}
bool operator>=(const big_int &lhs, const big_int &rhs)
{
return !(lhs < rhs);
}
bool operator>(const big_int &lhs, const big_int &rhs)
{
return rhs < lhs;
}
ostream& operator<<(ostream& _OStr, const big_int& rhs)
{
if(rhs.sign == BI_NEG) _OStr << '-';
_OStr << rhs.number[rhs.number.size() - 1];
for(int i = rhs.number.size() - 2; i >= 0; --i)
{
_OStr << rhs.number[i] / 1000 << (rhs.number[i] % 1000) / 100
<< (rhs.number[i] % 100) / 10 << rhs.number[i] % 10;
}
return _OStr;
}
const big_int bipow(const big_int &lhs, const int rhs)
{
assert(rhs >= 0);
big_int res(1);
for(int i = 0; i < rhs; ++i)
{
res *= lhs;
}
return res;
}
const big_int bifact(int n)
{
big_int res(1);
for(int i = 2; i <= n; ++i)
{
res *= i;
}
return res;
}