大数四则运算类

#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;
}

 

posted @ 2010-05-31 17:20  Yang Enzo  阅读(363)  评论(0编辑  收藏  举报