大整数类加法与乘法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//copyright@ 2011/03/06 yansha
//实现大整数类
#include
#include
#include
using namespace std;

class CBigInt
{
public:
// input
friend istream& operator >> (istream &, CBigInt &);
// output
friend ostream& operator << (ostream &os, const CBigInt &value)
{
if (value.bigInt[0] == '-')
os << value.bigInt;
else
{
// 正数不输出符号
os << value.bigInt.substr(1);
}
return os;
}
friend bool operator == (const CBigInt &, const CBigInt &);
friend bool operator < (const CBigInt &lValue, const CBigInt &rValue)
{
if (lValue.bigInt[0] != rValue.bigInt[0])
{
// '+'ASCII码为43,'-'ASCII码为45
return lValue.bigInt[0] > rValue.bigInt[0];
}
else
{
if (lValue.bigInt[0] == '+')
return lValue.smaller(rValue.bigInt); // 正数的情况
else
return lValue.greater(rValue.bigInt); // 负数的情况
}
}

friend bool operator > (const CBigInt &lValue, const CBigInt &rValue)
{
if (lValue.bigInt[0] != rValue.bigInt[0])
return lValue.bigInt[0] < rValue.bigInt[0];
else
{
if (lValue.bigInt[0] == '+')
return lValue.greater(rValue.bigInt);
else
return lValue.smaller(rValue.bigInt);
}
}
string bigInt;
public:
CBigInt();
CBigInt(int);
CBigInt(const string &);
CBigInt(const CBigInt &);
CBigInt(const char *);
CBigInt& operator = (const CBigInt &);
CBigInt& operator += (const CBigInt &);
CBigInt& operator -= (const CBigInt &);
CBigInt& operator *= (const CBigInt &);
CBigInt& operator /= (const CBigInt &);
CBigInt& operator %= (const CBigInt &);

// prefix increment
CBigInt& operator ++ ();
// prefix decrement
CBigInt& operator -- ();
// postfix increment
CBigInt operator ++ (int);
// postfix decrement
CBigInt operator -- (int);
private:
// unsigned +=
void plus(const string &);
// unsigned -=
void minus(const string &);
// unsigned ==
bool equal(const string &) const;
// unsigned <
bool smaller(const string &) const;
// unsigned >
bool greater(const string &) const;
};

/************************************************************************/
/* 构造函数
/************************************************************************/
// 默认构造函数
inline CBigInt::CBigInt() : bigInt("+0")
{}

// 构造函数
inline CBigInt::CBigInt(const string &str) : bigInt(str)
{
if (bigInt.size() > 0)
{
// 没有正负符号
if (bigInt[0] != '+' && bigInt[0] != '-')
{
string::size_type i = 0;
for (; i < bigInt.size() - 1 && bigInt[i] == '0'; i++);
if (i > 0)
bigInt.replace((string::size_type)0, i, "+");
else
bigInt.insert((string::size_type)0, 1, '+');
}
else
{
if (bigInt.size() == 1)
bigInt = "+0";
else
{
string::size_type j = 1;
// 去掉多余的0
for (; j < bigInt.size() - 1 && bigInt[

j] == '0'; j++);
if (j > 1)
bigInt.erase((string::size_type)1, j - 1);
if (bigInt == "-0")
bigInt = "+0";
}
}
}
else
bigInt = "+0";
}

// 复制构造函数
inline CBigInt::CBigInt(const CBigInt &value) : bigInt(value.bigInt)
{}

inline CBigInt::CBigInt(int num)
{
if (num == 0)
bigInt = "+0";
else if (num > 0)
bigInt = '+';
else
{
bigInt = '-';
num *= -1;
}
string temp = "";
while (num != 0)
{
temp += num % 10 + '0';
num = num / 10;
}
for (int i = temp.size() - 1; i >= 0; i--)
bigInt += temp[i];
}

inline CBigInt::CBigInt(const char *str) : bigInt(str)
{
if (bigInt.size() > 0)
{
if (bigInt[0] != '+' && bigInt[0] != '-')
{
string::size_type i = 0;
// 去除多余的0
for (; i < bigInt.size() - 1 && bigInt[i] == '0'; i++);
if (i > 0)
bigInt.replace((string::size_type)0, i, "+");
else
bigInt.insert((string::size_type)0, 1, '+');
}
else
{
if (bigInt.size() == 0)
bigInt = "+0";
else
{
string::size_type j = 1;
for (; j < bigInt.size() - 1 && bigInt[j] == '0'; j++);
if (j > 1)
bigInt.erase((string::size_type)1, j - 1);
// 处理特殊情况“-0”
if (bigInt == "-0")
bigInt = "+0";
}
}
}
else
bigInt = "+0";
}

inline bool operator == (const CBigInt &lValue, const CBigInt &rValue)
{
return lValue.bigInt == rValue.bigInt;
}

inline bool operator != (const CBigInt &lValue, const CBigInt &rValue)
{
return !(lValue.bigInt == rValue.bigInt);
}

inline bool operator <= (const CBigInt &lValue, const CBigInt &rValue)
{
return !(lValue > rValue);
}

inline bool operator >= (const CBigInt &lValue, const CBigInt &rValue)
{
return !(lValue < rValue);
}

inline CBigInt& CBigInt::operator = (const CBigInt &value)
{
bigInt = value.bigInt;
return *this;
}

// unsigned ==
inline bool CBigInt::equal(const string &value) const
{
return bigInt.substr(1) == value.substr(1);
}

// unsigned <
inline bool CBigInt::smaller(const string &value) const
{
if (bigInt.size() == value.size())
return bigInt.substr(1) < value.substr(1);
else
return bigInt.size() < value.size();
}

// unsigned >
inline bool CBigInt::greater(const string &value) const
{
if (bigInt.size() == value.size())
return bigInt.substr(1) > value.substr(1);
else
return bigInt.size() > value.size();
}

/************************************************************************/
/* 实现+,-,*,/运算
/************************************************************************/
void CBigInt::plus(const string &value)
{
if (bigInt.size() < value.size())
bigInt.insert((string::size_type)1, (value.size() - bigInt.size()), '0');
string::size_type i = bigInt.size() - 1;
string::size_type j = value.size() - 1;
while (j > 1)
{
bigInt[i] += value[j] - '0';
if (bigI

nt[i] > '9')
{
bigInt[i] -= 10;
++bigInt[i-1];
}
i--;
j--;
}

// 最高位进位
bigInt[i] += value[1] - '0';
while (i > 1 && bigInt[i] > '9')
{
bigInt[i] -= 10;
i--;
++bigInt[i];
}

if (bigInt[1] > '9')
{
bigInt[1] -= 10;
bigInt.insert((string::size_type)1, 1, '1');
}
}

void CBigInt::minus(const string &vlaue)
{
string::size_type i = bigInt.size() - 1;
string::size_type j = vlaue.size() - 1;
while (j >= 1)
{
bigInt[i] -= vlaue[j] - '0';
if (bigInt[i] < '0')
{
bigInt[i] += 10;
--bigInt[i-1];
}
i--;
j--;
}

// 向前借位
while (i > 1 && bigInt[i] < '0')
{
bigInt[i] += 10;
i--;
--bigInt[i];
}

// 去除多余的0
string::size_type k = 1;
for (; k < bigInt.size() - 1 && bigInt[k] == '0'; k++);
if (k > 1)
bigInt.erase((string::size_type)1, k - 1);
}

CBigInt& CBigInt::operator += (const CBigInt &value)
{
if (bigInt[0] == value.bigInt[0])
plus(value.bigInt);
else
{
// 互为相反数的情况
if (equal(value.bigInt))
bigInt = "+0";
// 绝对值小于的情况
else if (smaller(value.bigInt))
{
string temp = bigInt;
bigInt = value.bigInt;
minus(temp);
}
else
minus(value.bigInt);
}
return *this;
}

CBigInt& CBigInt::operator -= (const CBigInt &value)
{
// 处理过程与+=类似
if (bigInt[0] == value.bigInt[0])
{
if (equal(value.bigInt))
bigInt = "+0";
else if (smaller(value.bigInt))
{
string temp = bigInt;
bigInt = value.bigInt;
minus(temp);
if (bigInt[0] == '+')
bigInt[0] = '-';
else
bigInt[0] = '+';
}
else
minus(value.bigInt);
}
else
plus(value.bigInt);
return *this;
}

CBigInt operator + (const CBigInt &lValue, const CBigInt &rValue)
{
CBigInt sum(lValue);
sum += rValue;
return sum;
}

CBigInt operator - (const CBigInt &lValue, const CBigInt &rValue)
{
CBigInt diff(lValue);
diff -= rValue;
return diff;
}

// prefix increment
CBigInt& CBigInt::operator ++ ()
{
string::size_type i = bigInt.size() - 1;
if (bigInt[0] == '+')
{
++bigInt[i];
while (i > 1 && bigInt[i] > '9')
{
bigInt[i] -= 10;
i--;
++bigInt[i];
}

if (bigInt[i] > '9')
{
bigInt[i] -= 10;
bigInt.insert((string::size_type)1, 1, '1');
}
}
else
{
--bigInt[i];
while(i > 1 && bigInt[i] < '0')
{
bigInt[i] += 10;
i--;
--bigInt[i];
}

string::size_type j = 1;
for (; j < bigInt.size() - 1 && bigInt[j] == '0'; j++);
if (j > 1)
bigInt.erase(1, j - 1);

if (bigInt[1] == '0')
bigInt[0] = '+';
}
return *this;
}

CBigInt& CBigInt::operator -- ()
{
string::size_type i = bigInt.size() - 1;
// 对正数和负数分别处理
if (bigInt[0] == '+')
{
// 对0进行处理
if (bigInt[1] == '0')
bigInt = "-1";
else
{
--bigInt[i];
while (i > 1 && bigInt[i] < '0')
{
bigInt[i] += 10;

i--;
--bigInt[i];
}

string::size_type j = 1;
for (; j < bigInt.size() - 1 && bigInt[j] == '0'; j++);
if (j > 1)
bigInt.erase(1, j - 1);
}
}
else
{
++bigInt[i];
while (i > 1 && bigInt[i] > '9')
{
bigInt[i] -= 10;
i--;
++bigInt[i];
}

if (bigInt[1] > '9')
{
bigInt[1] += 10;
bigInt.insert((string::size_type)1, 1, '1');
}
}
return *this;
}

// postfix increment
CBigInt CBigInt::operator ++ (int)
{
CBigInt temp(*this);
++(*this);
return temp;
}

// postfix decrement
CBigInt CBigInt::operator -- (int)
{
CBigInt temp(*this);
--(*this);
return temp;
}

// 模拟笔算过程
CBigInt& CBigInt::operator *= (const CBigInt &value)
{
// 乘数或被乘数有一方为0则返回结果0
if (bigInt[1] == '0' || value.bigInt[1] == '0')
{
bigInt = "+0";
return *this;
}

string::size_type sizeofMultiplicand = bigInt.size();
string::size_type sizeofMultiplier = value.bigInt.size();
vector product(sizeofMultiplier + sizeofMultiplicand - 1);

// 初始化
for (string::size_type i = 1; i < sizeofMultiplicand; ++i)
bigInt[i] -= '0';


// 笔算乘法过程
for (string::size_type j = sizeofMultiplier - 1; j > 0; --j)
{
if (value.bigInt[j] > '0')
{
for (string::size_type k = sizeofMultiplicand - 1; k > 0; --k)
product[k+j] += bigInt[k] * (value.bigInt[j] - '0');
}
}

// 处理符号
if (bigInt[0] == value.bigInt[0])
product[0] = '+';
else
product[0] = '-';

vector::size_type sizeofProduct = product.size();
bigInt = string(sizeofProduct, '0');
bigInt[0] = product[0];

// 处理进位问题
for (vector::size_type n = sizeofProduct - 1; n > 1; --n)
{
product[n-1] += product[n] / 10;
product[n] %= 10;
bigInt[n] += product[n];
}

if (product[1] == 0)
bigInt.erase(1, 1);
else
bigInt[1] += product[1];

return *this;
}

// 重复做差法求商
CBigInt& CBigInt::operator /= (const CBigInt &value)
{
// 除数为0
if (value.bigInt == "+0")
{
bigInt = "*Error!";
return *this;
}

// 被除数大于除数
if (value.smaller(bigInt) == true)
{
string::size_type sizeofDividend = bigInt.size();
string::size_type sizeofDivisor = value.bigInt.size();
string answer(sizeofDividend, '0');

// 符号处理
if (bigInt[0] == value.bigInt[0])
answer[0] = '+';
else
answer[0] = '-';

string::size_type start = 1;
string::size_type end = sizeofDivisor - 1;

while (end < sizeofDividend)
{
// 试商过程,从高位到低位
while (value.greater(bigInt.substr(start - 1, end - start + 2)) ==

false)
{
string::size_type j = end;
// 减法过程
for (string::size_type i = sizeofDivisor - 1; i > 0; i--, j--)
{
bigInt[j] -= value.bigInt[i] - '0';
if (bigInt[j] < '0')
{
bigInt[j] += 10;
--bigInt

[j-1];
}
}

// 商的相应位加1
++answer[end];

// 以除数做边界去掉前缀0
while (start <= end && bigInt[start] == '0')
++start;
}

// 以被除数做边界去掉前缀0
while (start < sizeofDividend && bigInt[start] == '0')
++start;

// 如果end-start+1 < sizeofDivisor - 1,则进行补位
if (end - start + 2 < sizeofDivisor)
end = sizeofDivisor + start - 2;
else
++end;
}
start = 1;
for (; start < answer.size() - 1 && answer[start] == '0'; ++start);
if (start > 1)
answer.erase(1, start - 1);

bigInt = answer;
}
// 绝对值相等的情况
else if (value.equal(bigInt) == true)
{
string answer = "-1";
if (bigInt[0] == value.bigInt[0])
answer = "+1";
bigInt = answer;
}
else
bigInt = "+0";

return *this;
}

// 求余,与上面去商过程基本一致
CBigInt& CBigInt::operator %= (const CBigInt &value)
{
if (value.bigInt == "+0")
{
bigInt = "*Error!";
return *this;
}

// 求余,余数为剩余bigInt值
if (value.smaller(bigInt) == true)
{
string::size_type sizeofDivident = bigInt.size();
string::size_type sizeofDivisor = value.bigInt.size();

string::size_type start = 1;
string::size_type end = sizeofDivisor - 1;
while (end < sizeofDivident)
{
// 除数的值不大于被除数的值
while (value.greater(bigInt.substr(start - 1, end - start + 2)) ==

false)
{
string::size_type j = end;
for (string::size_type i = sizeofDivisor - 1; i > 0; --i, --j)
{
bigInt[j] -= value.bigInt[i] - '0';
if (bigInt[j] < '0')
{
bigInt[j] += 10;
--bigInt[j-1];
}
}

while (start <= end && bigInt[start] == '0')
++start;
}

while (start < sizeofDivident && bigInt[start] == '0')
++start;

if (end - start + 2 < sizeofDivisor)
end = sizeofDivisor + start - 2;
else
++end;
}

start = 1;
for (; start < sizeofDivident - 1 && bigInt[start] == '0'; start++);

if (start > 1)
bigInt.erase(1, start - 1);

if (bigInt == "-0")
bigInt[0] = '+';
}
else if (value.equal(bigInt))
bigInt = "+0";
return *this;
}

CBigInt operator * (const CBigInt &lValue, const CBigInt &rValue)
{
CBigInt product(lValue);
product *= rValue;
return product;
}

CBigInt operator / (const CBigInt &lValue, const CBigInt &rValue)
{
CBigInt quotient(lValue);
quotient /= rValue;
return quotient;
}

CBigInt operator % (const CBigInt &lValue, const CBigInt &rValue)
{
CBigInt mod(lValue);
mod %= rValue;
return mod;
}

相关文档
最新文档