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,
ALIGN_ZERO_RIGHT
};
public:
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';
}
CNumber abs(const CNumber &other)
{
CNumber num(other);
if (num.IsNegative()) num *= -1;
return num;
}
CNumber& operator++()
{
return operator+=(1);
}
CNumber operator++(const int)
{
CNumber numRet = *this;
operator+=(1);
return numRet;
}
CNumber& operator--()
{
return operator-=(1);
}
CNumber operator--(const int)
{
CNumber numRet = *this;
operator-=(1);
return numRet;
}
bool operator>(const CNumber &rhs) const
{
return gt(m_strNum, rhs.m_strNum);
}
bool operator<(const CNumber &rhs) const
{
return !(operator>(rhs));
}
bool operator==(const CNumber &rhs) const
{
return eq(m_strNum, rhs.m_strNum);
}
friend CNumber operator+(const CNumber &lhs, const CNumber &rhs);
CNumber& operator+=(const CNumber &rhs)
{
m_strNum = Add(m_strNum, rhs.m_strNum);
return *this;
}
friend CNumber operator-(const CNumber &lhs, const CNumber &rhs);
CNumber& operator-=(const CNumber &rhs)
{
if (*this == rhs)
{
m_strNum = "0";
return *this;
}
m_strNum = Subtract(m_strNum, rhs.m_strNum);
return *this;
}
friend CNumber operator*(const CNumber &lhs, const CNumber &rhs);
CNumber& operator*=(const CNumber &rhs)
{
m_strNum = Multiply(m_strNum, rhs.m_strNum);
return *this;
}
friend CNumber operator/(const CNumber &lhs, const CNumber &rhs);
CNumber& operator/=(const CNumber &rhs)
{
string strNumRemainder;
m_strNum = Divide(m_strNum, rhs.m_strNum, strNumRemainder);
return *this;
}
friend CNumber operator%(const CNumber &lhs, const CNumber &rhs);
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';
}
static void FormtNumStr(string &strNum)
{
switch (strNum.size())
{
case 0:
strNum = "0";
return;
case 1:
{
if (('-' == strNum[0]) || ('+' == strNum[0]))
{
strNum = "0";
return;
}
}
break;
}
if ('+' == strNum[0])
{
strNum.erase(0, 1);
}
if ('-' == strNum[0])
{
while (strNum.size() > 2)
{
if ('0' != strNum[1]) break;
strNum.erase(1, 1);
}
}
else
{
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))
{
num1.erase(0, 1);
return Subtract(num2, num1);
}
num2.erase(0, 1);
return Subtract(num1, num2);
}
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))
{
num2.insert(0, 1, '-');
}
else
{
num2.erase(0, 1);
}
return Add(num1, num2);
}
pLHS = &num1;
pRHS = &num2;
if (IsNegative(num1))
{
if (gt(num1, num2))
{
pLHS = &num2;
pRHS = &num1;
}
else
{
cSign = '-';
}
num1.erase(0, 1);
num2.erase(0, 1);
}
else
{
if (gt(num1, num2))
{
;
}
else
{
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'));
}
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,
ALIGN_ZERO_RIGHT
};
public:
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;
}
CNumber abs(const CNumber &other)
{
CNumber num(other);
if (num.IsNegative()) num.m_bNegatave = false;
return num;
}
CNumber& operator++()
{
return operator+=(1);
}
CNumber operator++(const int)
{
CNumber numRet = *this;
operator+=(1);
return numRet;
}
CNumber& operator--()
{
return operator-=(1);
}
CNumber operator--(const int)
{
CNumber numRet = *this;
operator-=(1);
return numRet;
}
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])
{
return IsNegative() ? false : true;
}
return IsNegative() ? true : false;
}
return false;
}
bool operator>=(const CNumber &rhs) const
{
return operator>(rhs) || operator==(rhs);
}
bool operator<(const CNumber &rhs) const
{
if (operator==(rhs)) return false;
return !(operator>(rhs));
}
bool operator<=(const CNumber &rhs) const
{
return operator<(rhs) || operator==(rhs);
}
bool operator==(const CNumber &rhs) const
{
if (IsNegative() != rhs.IsNegative()) return false;
return eq(m_vNum, rhs.m_vNum);
}
friend CNumber operator+(const CNumber &lhs, const CNumber &rhs);
CNumber& operator+=(const CNumber &rhs)
{
bool bSameSign = IsNegative() == rhs.IsNegative();
CNumber numRHS(rhs);
if (!bSameSign)
{
if (IsNegative())
{
m_bNegatave = false;
numRHS.operator -= (*this);
*this = numRHS;
}
else
{
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;
}
friend CNumber operator-(const CNumber &lhs, const CNumber &rhs);
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())
{
numRHS.m_bNegatave = true;
operator += (numRHS);
}
else
{
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;
}
friend CNumber operator*(const CNumber &lhs, const CNumber &rhs);
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)
{
numTemp.m_vNum.insert(numTemp.m_vNum.end(), nMul10, 0);
}
numMul += numTemp;
}
m_vNum.swap(numMul.m_vNum);
return *this;
}
friend CNumber operator/(const CNumber &lhs, const CNumber &rhs);
CNumber& operator/=(const CNumber &rhs)
{
CNumber remainder;
*this = Divide(*this, rhs, remainder);
return *this;
}
friend CNumber operator%(const CNumber &lhs, const CNumber &rhs);
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])
{
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;
}