C++ 大整数运算

//copyright@ 2011/03/06 yansha  
//实现大整数类  
#include <string>  
#include <vector>  
#include <iostream>  
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 (bigInt[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<unsigned int> 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<unsigned int>::size_type sizeofProduct = product.size();  
    bigInt = string(sizeofProduct, '0');  
    bigInt[0] = product[0];  
      
    // 处理进位问题  
    for (vector<unsigned int>::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;  
} 


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值