数字字符串四则运算

来源:互联网 发布:电脑锣编程代码 编辑:程序博客网 时间:2024/06/06 04:30

string版本

#include <stdio.h>#include <string>#define ASSERT(b) \    printf("%s : %s\n", #b, b ? "OK" : "Fail");using namespace std;class CNumber{    enum AlignZeroFlag    {        ALIGN_ZERO_LEFT, //对齐时左侧填充0        ALIGN_ZERO_RIGHT //对齐时右侧填充0    };public:    //数字字符顺序 123456 => CNumber m_strNum[0] = '1'    CNumber() : m_strNum("0")    {    }    CNumber(const char *num) : m_strNum(num)    {        FormtNumStr(m_strNum);    }    CNumber(const int num)    {        Num2Str(num, m_strNum);    }    CNumber(const CNumber &other)    {        m_strNum = other.m_strNum;    }    CNumber& operator=(const CNumber &rhs)    {        if (this != &rhs)        {            m_strNum = rhs.m_strNum;        }        return *this;    }    bool IsNegative() const    {        return IsNegative(m_strNum);    }    bool IsZero() const    {        return m_strNum[0] == '0';    }    //abs(CNumber)    CNumber abs(const CNumber &other)    {        CNumber num(other);        if (num.IsNegative()) num *= -1;        return num;    }    //++CNumber    CNumber& operator++()    {        return operator+=(1);    }    //CNumber++    CNumber operator++(const int)    {        CNumber numRet = *this;        operator+=(1);        return numRet;    }    //--CNumber    CNumber& operator--()    {        return operator-=(1);    }    //CNumber--    CNumber operator--(const int)    {        CNumber numRet = *this;        operator-=(1);        return numRet;    }    //CNumber > CNumber    bool operator>(const CNumber &rhs) const    {        return gt(m_strNum, rhs.m_strNum);      }    //CNumber < CNumber    bool operator<(const CNumber &rhs) const    {        return !(operator>(rhs));    }    //CNumber == CNumber    bool operator==(const CNumber &rhs) const    {               return eq(m_strNum, rhs.m_strNum);    }    //CNumber + CNumber    friend CNumber operator+(const CNumber &lhs, const CNumber &rhs);    //CNumber += CNumber;    CNumber& operator+=(const CNumber &rhs)    {        m_strNum = Add(m_strNum, rhs.m_strNum);        return *this;    }    //CNumber - CNumber    friend CNumber operator-(const CNumber &lhs, const CNumber &rhs);    //CNumber -= CNumber;    CNumber& operator-=(const CNumber &rhs)    {        if (*this == rhs)        {            m_strNum = "0";            return *this;        }        m_strNum = Subtract(m_strNum, rhs.m_strNum);        return *this;    }    //CNumber * CNumber    friend CNumber operator*(const CNumber &lhs, const CNumber &rhs);    //CNumber *= CNumber;    CNumber& operator*=(const CNumber &rhs)    {        m_strNum = Multiply(m_strNum, rhs.m_strNum);        return *this;    }    //CNumber / CNumber    friend CNumber operator/(const CNumber &lhs, const CNumber &rhs);    //CNumber /= CNumber;    CNumber& operator/=(const CNumber &rhs)    {        string strNumRemainder;        m_strNum = Divide(m_strNum, rhs.m_strNum, strNumRemainder);        return *this;    }    //CNumber % CNumber    friend CNumber operator%(const CNumber &lhs, const CNumber &rhs);    //CNumber %= CNumber;    CNumber& operator%=(const CNumber &rhs)    {        Divide(m_strNum, rhs.m_strNum, m_strNum);         return *this;    }public:    //数字转换为字符串    static void Num2Str(int n, string &strNum)    {        if (n == 0)        {            strNum = "0";            return;        }        char    cSign = 0;        strNum.clear();        if (n < 0)        {            cSign = '-';            n = -n;        }        while (n > 0)        {            strNum.insert(strNum.begin(), char((n%10) + '0'));            n /= 10;        }        if (cSign)        {            strNum.insert(strNum.begin(), cSign);        }    }    //负数判定    static bool IsNegative(const string &num)    {        if (0 == num.size()) return false;        return (num[0] == '-');    }    //零判定    static bool IsZero(const string &num)    {        if (0 == num.size()) return true;        return num[0] == '0';    }    //去除数字前面的'+'号及'0'字符    static void FormtNumStr(string &strNum)    {        switch (strNum.size())        {        case 0:            //"" => "0"            strNum = "0";            return;        case 1:            {                //"-" or "+" => "0"                if (('-' == strNum[0]) || ('+' == strNum[0]))                {                    strNum = "0";                    return;                }            }            break;        }        //+5 => 5        if ('+' == strNum[0])        {            strNum.erase(0, 1);        }        if ('-' == strNum[0])        {            //-0005 => -5            while (strNum.size() > 2)            {                if ('0' != strNum[1]) break;                strNum.erase(1, 1);            }        }        else        {            //0005 => 5            while (strNum.size() > 1)            {                if ('0' != strNum[0]) break;                strNum.erase(0, 1);            }        }    }    //对齐数字    static void AlignNumStr(string &strNum1, string &strNum2, AlignZeroFlag flag)    {        FormtNumStr(strNum1);        FormtNumStr(strNum2);        size_t nNumOffset1  = strNum1[0] == '-' ? 1 : 0;        size_t nNumOffset2  = strNum2[0] == '-' ? 1 : 0;        size_t nNum1Length  = strNum1.size() - nNumOffset1;        size_t nNum2Length  = strNum2.size() - nNumOffset2;        size_t nFixCnt      = 0;        size_t nFixOffset   = 0;        string *pStrNumToFix= NULL;        if (nNum1Length == nNum2Length) return;        if (nNum1Length > nNum2Length)        {            nFixCnt         = nNum1Length - nNum2Length;            nFixOffset      = nNumOffset2;            pStrNumToFix    = &strNum2;        }        else        {            nFixCnt         = nNum2Length - nNum1Length;            nFixOffset      = nNumOffset1;            pStrNumToFix    = &strNum1;        }        string &strFixNum   = *pStrNumToFix;        if (ALIGN_ZERO_LEFT == flag)        {            strFixNum.insert(nFixOffset, nFixCnt, '0');        }        else        {            strFixNum.insert(strFixNum.size(), nFixCnt, '0');        }    }    //取绝对值    static string abs(const string &num)    {        string strRes(num);        FormtNumStr(strRes);        if (IsNegative(strRes))        {            strRes.erase(0, 1);        }        return strRes;    }    //相等    static bool eq(const string &strNum1, const string &strNum2)    {        string num1(strNum1), num2(strNum2);        AlignNumStr(num1, num2, ALIGN_ZERO_LEFT);        //符号不同        if (IsNegative(num1) != IsNegative(num2)) return false;        //相同符号        for (size_t i = 0; i < num1.size(); ++i)        {            if (num1[i] != num2[i]) return false;        }        return true;    }    //大于    static bool gt(const string &strNum1, const string &strNum2)    {        bool bSameSign = IsNegative(strNum1) == IsNegative(strNum2);        if (!bSameSign)        {            if (IsNegative(strNum1)) return false;            return true;        }        string num1(strNum1), num2(strNum2);        AlignNumStr(num1, num2, ALIGN_ZERO_LEFT);        for (size_t i = 0; i < num1.size(); ++i)        {            if (num1[i] == num2[i]) continue;            if (num1[i] > num2[i])            {                return IsNegative(num1) ? false : true;            }            else            {                return IsNegative(num1) ? true : false;            }        }        return false;    }    //大于等于    static bool gte(const string &strNum1, const string &strNum2)    {        return gt(strNum1, strNum2) || eq(strNum1, strNum1);    }    //小于    static bool lt(const string &strNum1, const string &strNum2)    {        if (eq(strNum1, strNum2)) return false;        return !gt(strNum1, strNum2);    }    //小于等于    static bool lte(const string &strNum1, const string &strNum2)    {        return lt(strNum1, strNum2) || eq(strNum1, strNum2);    }    //加    static string Add(const string &strNum1, const string &strNum2)    {        string  strSum, num1(strNum1), num2(strNum2);        AlignNumStr(num1, num2, ALIGN_ZERO_LEFT);        if (IsNegative(num1) != IsNegative(num2))        {            if (IsNegative(num1))            {                //-10 + 5                num1.erase(0, 1);                return Subtract(num2, num1);            }            //10 + (-5)            num2.erase(0, 1);            return Subtract(num1, num2);        }        //5 + 10        //-5 + (-10)        size_t  nNumOffset  = num1[0] == '-' ? 1 : 0;        int     nSum(0), nCA(0);        strSum.resize(num1.size());        if (nNumOffset) strSum[0] = '-';//设置负号标志        for (size_t i = num1.size(), idx; i > nNumOffset; --i)        {            idx     = i - 1;            nSum    = (num1[idx] - '0') + (num2[idx] - '0') + nCA;            nCA     = nSum / 10;            nSum    %= 10;            strSum[idx] = char(nSum + '0');        }        if (nCA)        {            strSum.insert(nNumOffset, 1, char(nCA + '0'));        }        return strSum;    }    //减    static string Subtract(const string &strNum1, const string &strNum2)    {        string  strResult("0"), num1(strNum1), num2(strNum2);        string  *pLHS(NULL), *pRHS(NULL);        char    cSign(0);        AlignNumStr(num1, num2, ALIGN_ZERO_LEFT);        if (eq(num1, num2)) return strResult;        bool bSameSign = IsNegative(num1) == IsNegative(num2);        if (!bSameSign)        {            if (IsNegative(num1))            {                //-10 - 5                num2.insert(0, 1, '-');                         }            else            {                //10 - (-5)                num2.erase(0, 1);            }            return Add(num1, num2);                 }        pLHS = &num1;        pRHS = &num2;        if (IsNegative(num1))        {            if (gt(num1, num2))            {                //-5 - (-10)                pLHS = &num2;                pRHS = &num1;            }            else            {                //-10 - (-5)                cSign = '-';            }            //去除负号标志            num1.erase(0, 1);            num2.erase(0, 1);        }        else        {            //10 - 5            if (gt(num1, num2))            {                ;            }            else            {                //5 - 10                pLHS = &num2;                pRHS = &num1;                cSign = '-';            }        }        string &strLHS = *pLHS;        string &strRHS = *pRHS;        strResult.resize(strLHS.size());        for (size_t i = strLHS.size(), idx; i > 0; --i)        {            idx = i - 1;            if (strLHS[idx] >= strRHS[idx])            {                strLHS[idx] = strLHS[idx] - strRHS[idx] + '0';                continue;            }            strLHS[idx] = 10 + (strLHS[idx] - strRHS[idx]) + '0';            for (size_t j = idx; j > 0; --j)            {                if (strLHS[j - 1] != '0')                {                    --strLHS[j - 1];                    break;                }                strLHS[j - 1] = '9';            }        }        if (cSign)        {            strLHS.insert(0, 1, cSign);        }        strResult = strLHS;        return strResult;    }    //乘    static string Multiply(const string &strNum1, const string &strNum2)    {        string strResult("0"), num1(strNum1), num2(strNum2);        FormtNumStr(num1);        FormtNumStr(num2);        if (IsZero(num1) || IsZero(num2)) return strResult;        if (eq(num1, "-1"))        {            if (IsNegative(num2))            {                num2.erase(0, 1);            }            else            {                num2.insert(0, 1, '-');            }            return num2;        }        if (eq(num2, "-1"))        {            if (IsNegative(num1))            {                num1.erase(0, 1);            }            else            {                num1.insert(0, 1, '-');            }            return num1;        }        bool    bSameSign = IsNegative(num1) == IsNegative(num2);               char    cSign = bSameSign ? 0 : '-';                string  *pLHS(NULL), *pRHS(NULL);        if (IsNegative(num1)) num1.erase(0, 1);        if (IsNegative(num2)) num2.erase(0, 1);        pLHS = &num1;        pRHS = &num2;        //多位数作为被乘数        if (num1.size() < num2.size())        {            pLHS = &num2;            pRHS = &num1;        }        string  &strLHS = *pLHS;        string  &strRHS = *pRHS;        string  strTmp;        int     n1, n2;        int     nMul(0);        int     nCA(0);        strResult.clear();        for (size_t i = strRHS.size(), idx = 0; i > 0; --i, ++idx)        {            n1 = strRHS[i - 1] - '0';            strTmp.clear();            strTmp.resize(strLHS.size());            for (size_t j = strLHS.size(); j > 0; --j)            {                n2      = strLHS[j - 1] - '0';                nMul    = n1 * n2 + nCA;                nCA     = nMul / 10;                nMul    %= 10;                strTmp[j - 1] = nMul + '0';                         }            if (nCA)            {                strTmp.insert(0, 1, char(nCA + '0'));            }            //x10^n            strTmp.insert(strTmp.size(), idx, '0');            strResult = Add(strResult, strTmp);        }        if (cSign)        {            strResult.insert(0, 1, cSign);        }        return strResult;    }    //乘    static string Multiply(const string &strNum1, int n)    {        string strNum2;        Num2Str(n, strNum2);        return Multiply(strNum1, strNum2);    }    //除    static string Divide(const string &strNum1, const string &strNum2, string &numRemainder)    {        string strResult("0"), num1(strNum1), num2(strNum2), strMul, strSub;        numRemainder = "0";        FormtNumStr(num1);        FormtNumStr(num2);        if (IsZero(strNum2)) return strResult;        bool bSameSign = IsNegative(num1) == IsNegative(num2);        char cSign = bSameSign ? 0 : '-';        if (lt(abs(num1), abs(num2)))        {            numRemainder = num1;            return strResult;        }        if (eq(abs(num1), abs(num2)))        {            strResult = "1";            if (cSign) strResult.insert(0, 1, cSign);            return strResult;        }        if (IsNegative(num1)) num1.erase(0, 1);        if (IsNegative(num2)) num2.erase(0, 1);        //商位数               size_t num1Length   = num1.size();        size_t num2Length   = num2.size();        size_t nLoopCnt     = num1Length - num2Length + 1;        strResult.resize(nLoopCnt);        numRemainder = num1.substr(0, num2.size());        for (size_t i = 0; i < nLoopCnt; ++i)        {            if (gte(numRemainder, num2))            {                int n = (numRemainder[0] - '0')/(num2[0] - '0' + 1);                while (1)                {                    strMul = Multiply(num2, n);                    strSub = Subtract(numRemainder, strMul);                    if (lt(strSub, num2))                    {                        break;                    }                    ++n;                }                strResult[i] = char(n + '0');                numRemainder = strSub;            }            else            {                strResult[i] = '0';            }            numRemainder += num1[num2Length + i];            FormtNumStr(numRemainder);        }        if (cSign) strResult.insert(0, 1, cSign);        return strResult;    }private:    string m_strNum;};CNumber operator+(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet += rhs;    return numRet;}CNumber operator-(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet -= rhs;    return numRet;}CNumber operator*(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet *= rhs;    return numRet;}CNumber operator/(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet /= rhs;    return numRet;}CNumber operator%(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet %= rhs;    return numRet;}void calc1(const CNumber &num1, const CNumber &num2, CNumber &numSum, CNumber &numSub, CNumber &numMul, CNumber &numDiv){    numSum = num1 + num2;    numSub = num1 - num2;    numMul = num1 * num2;    numDiv = num1 / num2;}int main(){    CNumber num1, num2, numSum, numSub, numMul, numDiv;    if (0) {        ASSERT(CNumber::lt("-99", "-90"));        ASSERT(CNumber::lte("-99", "-99"));        ASSERT(CNumber::lte("-99", "-100") == false);        ASSERT(CNumber::lt("-99", "-100") == false);        ASSERT(CNumber::lt("-9", "10"));        ASSERT(CNumber::lt("5", "10"));        ASSERT(CNumber::lte("10", "10"));    }    if (0) {        num1 = "99";        num2 = "-100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "-1");        ASSERT(numSub == "199");        ASSERT(numMul == "-9900");        ASSERT(numDiv == "0");    }    if (1) {        string strRemainder, sTmp;        int n = 19 % 8;        CNumber::Divide("19", "8", strRemainder);        CNumber::Num2Str(n, sTmp);        ASSERT(sTmp == "3");    }    if (0) {        calc1(num2, num1, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "-1");        ASSERT(numSub == "-199");    }    if (0) {        num1 = "-99";        num2 = "10";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "-89");        ASSERT(numSub == "-109");        ASSERT(numMul == "-990");        ASSERT(numDiv == "-9");    }    if (0) {        num1 = "100";        num2 = "100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "200");        ASSERT(numSub == "0");        ASSERT(numMul == "10000");        ASSERT(numDiv == "1");    }    if (0) {        num1 = "-100";        num2 = "100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "0");        ASSERT(numSub == "-200");        ASSERT(numMul == "-10000");        ASSERT(numDiv == "-1");    }    if (1) {        num1 = "55";        num2 = "100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "155");        ASSERT(numSub == "-45");        ASSERT(numMul == "5500");        ASSERT(numDiv == "0");    }    return 0;}

vector版本

#include <stdio.h>#include <string>#include <vector>#define ASSERT(b) \    printf("%s : %s\n", #b, b ? "OK" : "Fail");using namespace std;class CNumber{    typedef vector<char> vecNum;    enum AlignZeroFlag    {        ALIGN_ZERO_LEFT, //对齐时左侧填充0        ALIGN_ZERO_RIGHT //对齐时右侧填充0    };public:    //数字字符顺序 123456 => CNumber m_vNum[0] = 1    CNumber() : m_bNegatave(false)    {        m_vNum.push_back(0);    }    CNumber(const char *num)    {        SetNum(num);    }    CNumber(const int num)    {        SetNum(num);    }    CNumber(const CNumber &other)    {        m_bNegatave = other.m_bNegatave;        m_vNum      = other.m_vNum;    }    CNumber& operator=(const CNumber &rhs)    {        if (this != &rhs)        {            m_bNegatave = rhs.m_bNegatave;            m_vNum      = rhs.m_vNum;        }        return *this;    }    bool IsNegative() const    {        return m_bNegatave;    }    bool IsZero() const    {        return m_vNum[0] == 0;    }    //abs(CNumber)    CNumber abs(const CNumber &other)    {        CNumber num(other);        if (num.IsNegative()) num.m_bNegatave = false;        return num;    }    //++CNumber    CNumber& operator++()    {        return operator+=(1);    }    //CNumber++    CNumber operator++(const int)    {        CNumber numRet = *this;        operator+=(1);        return numRet;    }    //--CNumber    CNumber& operator--()    {        return operator-=(1);    }    //CNumber--    CNumber operator--(const int)    {        CNumber numRet = *this;        operator-=(1);        return numRet;    }    //CNumber > CNumber    bool operator>(const CNumber &rhs) const    {        if (IsZero() && rhs.IsZero()) return false;        if (IsNegative() != rhs.IsNegative())        {            //不同符号            if (IsNegative()) return false;            return true;        }        //相同符号        if (m_vNum.size() != rhs.m_vNum.size())        {            //不同长度            if (m_vNum.size() > rhs.m_vNum.size())            {                return IsNegative() ? false : true;            }            return IsNegative() ? true : false;        }        for (size_t i = 0; i < m_vNum.size(); ++i)        {            if (m_vNum[i] == rhs.m_vNum[i]) continue;            if (m_vNum[i] > rhs.m_vNum[i])            {                //-9 < -8 || 9 > 8                return IsNegative() ? false : true;            }            //-8 > -9 || 8 < 9            return IsNegative() ? true : false;        }        return false;    }    //CNumber >= CNumber    bool operator>=(const CNumber &rhs) const    {        return operator>(rhs) || operator==(rhs);    }    //CNumber < CNumber    bool operator<(const CNumber &rhs) const    {        if (operator==(rhs)) return false;        return !(operator>(rhs));    }    //CNumber <= CNumber    bool operator<=(const CNumber &rhs) const    {        return operator<(rhs) || operator==(rhs);    }    //CNumber == CNumber    bool operator==(const CNumber &rhs) const    {               if (IsNegative() != rhs.IsNegative()) return false;        return eq(m_vNum, rhs.m_vNum);    }    //CNumber + CNumber    friend CNumber operator+(const CNumber &lhs, const CNumber &rhs);    //CNumber += CNumber;    CNumber& operator+=(const CNumber &rhs)    {        bool    bSameSign = IsNegative() == rhs.IsNegative();        CNumber numRHS(rhs);        if (!bSameSign)        {            //不同符号            if (IsNegative())            {                //-m + n                m_bNegatave = false;                numRHS.operator -= (*this);                *this = numRHS;            }            else            {                //m + -n                numRHS.m_bNegatave = false;                operator -=(numRHS);            }            return *this;        }        //相同符号        int     nCA(0), nSum(0);        AlignNum(m_vNum, numRHS.m_vNum, ALIGN_ZERO_LEFT);        for (size_t i = m_vNum.size(), idx; i > 0; --i)        {            idx     = i - 1;            nSum    = nCA + m_vNum[idx] + numRHS.m_vNum[idx];            nCA     = nSum / 10;            nSum    %= 10;            m_vNum[idx] = nSum;        }        if (nCA) m_vNum.insert(m_vNum.begin(), 1, (char)nCA);        return *this;    }    //CNumber - CNumber    friend CNumber operator-(const CNumber &lhs, const CNumber &rhs);    //CNumber -= CNumber;    CNumber& operator-=(const CNumber &rhs)    {        if (*this == rhs)        {            SetNum((int)0);            return *this;        }        bool    bSameSign = IsNegative() == rhs.IsNegative();        CNumber numRHS(rhs);        if (!bSameSign)        {            if (IsNegative())            {                //-m - n                numRHS.m_bNegatave = true;                operator += (numRHS);            }            else            {                //m - (-n)                numRHS.m_bNegatave = false;                operator += (numRHS);            }            return *this;        }        AlignNum(m_vNum, numRHS.m_vNum, ALIGN_ZERO_LEFT);        int n1, n2, nSub;        m_bNegatave = *this < numRHS;        if (m_bNegatave)        {            m_vNum.swap(numRHS.m_vNum);        }        for (size_t i = m_vNum.size(), idx; i > 0; --i)        {            idx = i - 1;            n1  = m_vNum[idx];            n2  = numRHS.m_vNum[idx];            nSub= n1 - n2;            if (nSub < 0)            {                nSub += 10;//转换为正数                for (size_t j = idx; j > 0; --j)                {                    if (m_vNum[j - 1] != 0)                    {                        --m_vNum[j - 1];                        break;                    }                    m_vNum[j - 1] = 9;                }            }            m_vNum[idx] = (char)nSub;        }        FormatNum(m_vNum);        return *this;    }    //CNumber * CNumber    friend CNumber operator*(const CNumber &lhs, const CNumber &rhs);    //CNumber *= CNumber;    CNumber& operator*=(const CNumber &rhs)    {        if (IsZero() || rhs.IsZero())        {            SetNum((int)0);            return *this;        }        bool    bSameSign = IsNegative() == rhs.IsNegative();        CNumber numRHS(rhs), numMul, numTemp;        int     n1, n2, nMul, nCA(0);        m_bNegatave = !bSameSign;//设置符号        if (m_vNum.size() < numRHS.m_vNum.size())        {            m_vNum.swap(numRHS.m_vNum);        }        numMul.SetNum((int)0);        for (size_t i = numRHS.m_vNum.size(), nMul10(0); i > 0; --i, ++nMul10)        {            n1 = numRHS.m_vNum[i-1];            numTemp.SetNum((int)0);            numTemp.m_vNum.resize(m_vNum.size());            for (size_t j = m_vNum.size(); j > 0; --j)            {                n2      = m_vNum[j - 1];                nMul    = n1 * n2 + nCA;                nCA     = nMul / 10;                nMul    %= 10;                numTemp.m_vNum[j - 1] = (char)nMul;            }            if (nCA) numTemp.m_vNum.insert(numTemp.m_vNum.begin(), 1, (char)nCA);            if (nMul10)            {                //x 10^n                numTemp.m_vNum.insert(numTemp.m_vNum.end(), nMul10, 0);            }            numMul += numTemp;        }        m_vNum.swap(numMul.m_vNum);        return *this;    }    //CNumber / CNumber    friend CNumber operator/(const CNumber &lhs, const CNumber &rhs);    //CNumber /= CNumber;    CNumber& operator/=(const CNumber &rhs)    {        CNumber remainder;        *this = Divide(*this, rhs, remainder);        return *this;    }    //CNumber % CNumber    friend CNumber operator%(const CNumber &lhs, const CNumber &rhs);    //CNumber %= CNumber;    CNumber& operator%=(const CNumber &rhs)    {        Divide(*this, rhs, *this);         return *this;    }    static CNumber Divide(const CNumber &lhs, const CNumber &rhs, CNumber &remainder)    {        CNumber numRet, numMul;        bool    bSameSign   = lhs.IsNegative() == rhs.IsNegative();        numRet.m_bNegatave  = !bSameSign;//设置符号        if (eq(lhs.m_vNum, rhs.m_vNum))        {            remainder.SetNum((int)0);            numRet.SetNum(1);            numRet.m_bNegatave = !bSameSign;            return numRet;        }        if (lt(lhs.m_vNum, rhs.m_vNum))        {            numRet.SetNum((int)0);            remainder = lhs;            return numRet;        }        size_t num1Length   = lhs.m_vNum.size();        size_t num2Length   = rhs.m_vNum.size();        //商位数          size_t nLoopCnt     = num1Length - num2Length + 1;        numRet.m_vNum.resize(nLoopCnt);        remainder.m_vNum.clear();        remainder.m_vNum.resize(rhs.m_vNum.size());        for (size_t i = 0; i < rhs.m_vNum.size(); ++i)        {            remainder.m_vNum[i] = lhs.m_vNum[i];        }        //全部设置为正数        for (size_t i = 0; i < nLoopCnt; ++i)        {            if (i != 0) remainder.m_vNum.push_back(lhs.m_vNum[num2Length + i]);            if (gte(remainder.m_vNum, rhs.m_vNum))            {                int n = 0;                if (remainder.m_vNum[i] < rhs.m_vNum[i])                {                    //5/9                    if (remainder.m_vNum.size() == rhs.m_vNum.size())                    {                        numRet.m_vNum[i] = 0;                        continue;                    }                    n = (remainder.m_vNum[0]*10 + remainder.m_vNum[1]) / rhs.m_vNum[0];                }                else                {                    n = remainder.m_vNum[0] / rhs.m_vNum[0];                }                while (1)                {                    numMul = rhs * n;                    if (lt(numMul.m_vNum ,remainder.m_vNum))                    {                        remainder -= numMul;                        break;                    }                    --n;                }                numRet.m_vNum[i] = (char)n;                FormatNum(remainder.m_vNum);            }            else            {                numRet.m_vNum[i] = 0;            }        }        FormatNum(numRet.m_vNum);        return numRet;    }private:    static bool gt(const vecNum &num1, const vecNum &num2)    {        if (num1.size() > num2.size()) return true;        if (num1.size() < num2.size()) return false;        for (size_t i = 0; i < num1.size(); ++i)        {            if (num1[i] == num2[i]) continue;            if (num1[i] > num2[i]) return true;            return false;        }        return false;    }    static bool eq(const vecNum &num1, const vecNum &num2)    {        if (num1.size() != num2.size()) return false;        for (size_t i = 0; i < num1.size(); ++i)        {            if (num1[i] != num2[i]) return false;        }        return true;    }    static bool lt(const vecNum &num1, const vecNum &num2)    {        if (eq(num1, num2)) return false;        return !gt(num1, num2);    }    static bool gte(const vecNum &num1, const vecNum &num2)    {        return gt(num1, num2) || eq(num1, num2);    }    static void FormatNum(vecNum &num)    {        if (num.size() == 0)        {            num.push_back(0);            return;        }        while (num.size() > 1)        {            if (num[0] != 0) break;            num.erase(num.begin());        }    }private:    void SetNum(const char *szNum)    {        size_t nLen(0);        m_bNegatave = false;        if ((NULL == szNum) || ((nLen = strlen(szNum)) == 0))        {            m_vNum.push_back(0);            return;        }        char c(0);        for (size_t i = 0; i < nLen; ++i)        {            c = szNum[i];            if (i == 0)            {                if (c == '+') continue;                if (c == '-')                {                    m_bNegatave = true;                    continue;                }            }            if ((c >= '0') && (c <= '9'))            {                m_vNum.push_back(c - '0');            }        }        if (m_vNum.empty()) m_vNum.push_back(0);    }    void SetNum(int num)    {        m_bNegatave = (num < 0);        if (m_bNegatave) num *= -1;        m_vNum.clear();        while (num > 0)        {            m_vNum.insert(m_vNum.begin(), 1, num % 10);            num /= 10;        }        if (m_vNum.empty()) m_vNum.push_back(0);    }    void AlignNum(vecNum &num1, vecNum &num2, AlignZeroFlag flag)    {        size_t  nNumLenth1  = num1.size();        size_t  nNumLenth2  = num2.size();        vecNum  *pAlignNum  = &num2;        size_t  nAlignCnt   = nNumLenth1 - nNumLenth2;        if (nNumLenth1 == nNumLenth2) return;        if (nNumLenth1 < nNumLenth2)        {            pAlignNum   = &num1;            nAlignCnt   = nNumLenth2 - nNumLenth1;        }        if (ALIGN_ZERO_LEFT == flag)        {            pAlignNum->insert(pAlignNum->begin(), nAlignCnt, 0);        }        else        {            pAlignNum->insert(pAlignNum->end(), nAlignCnt, 0);        }    }private:    bool            m_bNegatave;    vector<char>    m_vNum;};CNumber operator+(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet += rhs;    return numRet;}CNumber operator-(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet -= rhs;    return numRet;}CNumber operator*(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet *= rhs;    return numRet;}CNumber operator/(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet /= rhs;    return numRet;}CNumber operator%(const CNumber &lhs, const CNumber &rhs){    CNumber numRet(lhs);    numRet %= rhs;    return numRet;}void calc1(const CNumber &num1, const CNumber &num2, CNumber &numSum, CNumber &numSub, CNumber &numMul, CNumber &numDiv){    numSum = num1 + num2;    numSub = num1 - num2;    numMul = num1 * num2;    numDiv = num1 / num2;}int main(){    CNumber num1, num2, numSum, numSub, numMul, numDiv;    if (1) {        num1 = "99";        num2 = "-100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "-1");        ASSERT(numSub == "199");        ASSERT(numMul == "-9900");        ASSERT(numDiv == "0");    }    if (1) {        num1 = "-99";        num2 = "10";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "-89");        ASSERT(numSub == "-109");        ASSERT(numMul == "-990");        ASSERT(numDiv == "-9");    }    if (1) {        num1 = "100";        num2 = "100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "200");        ASSERT(numSub == "0");        ASSERT(numMul == "10000");        ASSERT(numDiv == "1");    }    if (1) {        num1 = "-100";        num2 = "100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "0");        ASSERT(numSub == "-200");        ASSERT(numMul == "-10000");        ASSERT(numDiv == "-1");    }    if (1) {        num1 = "55";        num2 = "100";        calc1(num1, num2, numSum, numSub, numMul, numDiv);        ASSERT(numSum == "155");        ASSERT(numSub == "-45");        ASSERT(numMul == "5500");        ASSERT(numDiv == "0");    }    return 0;}
0 0