Big data's operation of addition, subtraction, multiplication and division
BigData.h:
# ifndef _ _ BIG_DATA_H__#define _ _ BIG_DATA_H__#include # include typedef long long INT64;//#define MININT64-9223372036854775808 / / Compiler check error / # define MAXINT64 + 9223372036854775807 const INT64 MININT64 = + 9223372036854775807 + 1temp Const INT64 MAXINT64 = + 9223372036854775807 BigData {friend std::ostream& operator='0') & (* temp _ value = this- > _ value * 10 + (* temp -'0') This- > _ pdata [iCount + +] = * temp++;} this- > _ pData.resize (iCount); if (cSign = ='-') {this- > _ value = 0-this- > _ value;} if (! this- > _ IsINT64OverFlow ()) / overflow {this- > _ value = 0xCCCCCCCCCCCCCCCC }} / * BigData (const char* str) * / BigData BigData::operator+ (const BigData& bigData) {if (this- > _ IsINT64OverFlow () & & bigData._IsINT64OverFlow ()) / both have no overflow {if (this- > _ pData [0]! = bigData._pData [0]) / / different sign There must be no overflow {return BigData (this- > _ value + bigData._value) } else / / two identical {if ((this- > _ value > 0 & & MAXINT64-this- > _ value > = bigData._value) | | / / the result still has no overflow (this- > _ value_value _ value + bigData._value) } if (this- > _ pData [0] = = bigData._pData [0]) / / two identical {return BigData (this- > AddStr (bigData). C_str ());} BigData temp1 ((this- > _ pData) .c_str ()) / / there is overflow, different sign, call minus BigData temp2 ((bigData._pData). C_str ()); if (this- > _ pData [0] = ='+') {temp2._pData [0] ='+'; temp2._value = 0-temp2._value; return (temp1.SubStr (temp2)) .c_str () } else {temp1._pData [0] ='+'; temp1._value = 0-temp1._value; return (temp2.SubStr (temp1)) .c_str ();}} std::string BigData::AddStr (const BigData& bigData) const {std::string left = this- > _ pData; std::string right = bigData._pData Char cSign = this- > _ pData [0]; size_t iLSize = left.size (); size_t iRSize = right.size (); if (iLSize
< iRSize) { std::swap(left, right); std::swap(iLSize, iRSize); } std::string ret; ret.resize(iLSize + 1); ret[0] = cSign; int step = 0;//进位 for (size_t iCount = 1; iCount < iLSize; ++iCount) { char ch = left[iLSize - iCount] - '0' + step; if (iCount < iRSize) { ch += (right[iRSize - iCount] - '0'); } ret[iLSize - iCount + 1] = ch % 10 + '0'; step = ch / 10; } ret[1] = step + '0'; return ret;}BigData BigData::operator-(const BigData& bigData){ if (this->_ IsINT64OverFlow () & & bigData._IsINT64OverFlow () / / No overflow {if (this- > _ pData [0] = = bigData._pData [0]) / / same sign, after subtraction, there must be no overflow {return this- > _ value-bigData._value } else {if ((this- > _ value > 0 & & MAXINT64 + bigData._value > = this- > _ value) | (this- > _ value)
< 0 && MININT64 + bigData._value _value)) //结果无溢出 { return this->_ value-bigData._value;} if (this- > _ pData [0] = = bigData._pData [0]) {return BigData (this- > SubStr (bigData) .c_str ());} BigData temp ((bigData._pData) .c_str ()) / / different sign, overflow-3-5 color color 3 + (- 5) 3-(- 5) = 3-5 temp._pData [0] = this- > _ pData [0]; temp._value = 0-temp._value; return this- > AddStr (temp). C_str ();} / * operator-*/std::string BigData::SubStr (const BigData& bigData) const {std::string ret; std::string left = this- > _ pData Std::string right = bigData._pData; char cSign = this- > _ pData [0]; size_t iLSize = left.size (); size_t iRSize = right.size (); if (cSign = ='-') {std::swap (left, right); std::swap (iLSize, iRSize);} if ((iLSize
< iRSize) || (iLSize == iRSize && left < right)) { std::swap(left, right); std::swap(iLSize, iRSize); cSign = '-'; } else { cSign = '+'; } ret.resize(iLSize); ret[0] = cSign; char step = 0; for (size_t iCount = 1; iCount < iLSize; ++iCount) { int ch = left[iLSize - iCount] - '0' - step; if (iCount < iRSize) { ch -= (right[iRSize - iCount] - '0'); } if (ch < 0) { step = 1; ch = ch + 10; } else { step = 0; } ret[iLSize - iCount] = ch + '0'; } return ret;}/*SubStr(const BigData& bigData)*/BigData BigData::operator*(const BigData& bigData){ if (this->_ pData [1] = ='0' | | bigData._pData [1] = ='0') {return INT64 (0);} char cSign ='+'; if (this- > _ pData [0]! = bigData._pData [0]) {cSign ='-' } if (this- > _ pData [1] = ='1') {std::string ret = bigData._pData; ret [0] = cSign; return ret.c_str ();} if (bigData._pData [1] = ='1') {std::string ret = this- > _ pData Ret [0] = cSign; return ret.c_str () } if (this- > _ IsINT64OverFlow () & & bigData._IsINT64OverFlow ()) / / No overflow {if ((cSign = ='+') & & / / same sign and no result overflow ((this- > _ value > 0 & & MAXINT64 / this- > _ value > = bigData._value) | (this- > _ value)
< 0 && MAXINT64 / this->_ value _ value * bigData._value;} if ((cSign = ='-') & & / / different sign and the result does not overflow ((this- > _ value > 0 & & MININT64 / this- > _ value _ value)
< 0 && MININT64 / this->_ value > = bigData._value)) {return this- > _ value * bigData._value;}} return this- > MulStr (bigData). C_str ();} std::string BigData::MulStr (const BigData& bigData) const {char cSign ='+' If (this- > _ pData [0]! = bigData._pData [0]) {cSign ='-';} std::string left = this- > _ pData; std::string right = bigData._pData; size_t iLSize = left.size (); size_t iRSize = right.size (); std::string ret Ret.resize (iLSize + iRSize-1); ret [0] = cSign; if (iLSize
< iRSize) { std::swap(left, right); std::swap(iLSize, iRSize); } int step = 0; for (int iRCount = 0; iRCount < iRSize - 1; ++iRCount) { step = 0; int chR = right[iRSize - 1 - iRCount] - '0'; if (0 == chR) { continue; } for (int iLCount = 1; iLCount < (int)iLSize; ++iLCount) { int ch = chR * (left[iLSize - iLCount] - '0') + step + ret[iLSize + iRSize - 1 - iLCount - iRCount]; ret[iLSize + iRSize - 1 - iLCount - iRCount] = ch % 10; step = ch / 10; } ret[iRSize - iRCount - 1] += step; } for (int iCount = 1; iCount < iLSize + iRSize - 1; ++iCount) { ret[iCount] += '0'; } return ret.c_str();}BigData BigData::operator/(const BigData& bigData){ //right == 0 if (bigData._pData[1] == '0') assert(false); //left == 0 if (this->_ pData [1] = ='0') {return INT64 (0);} / / No overflow, so there must be no overflow if (this- > _ IsINT64OverFlow () & & bigData._IsINT64OverFlow ()) {return this- > _ value / bigData._value;} char cSign ='+' If (this- > _ pData [0]! = bigData._pData [0]) {cSign ='-';} size_t iLSize = this- > _ pData.size (); size_t iRSize = bigData._pData.size (); / / left
< right if ((iLSize < iRSize) || (iLSize == iRSize && strcmp(this->_ pData.c_str () + 1, bigData._pData.c_str () + 1)
< 0)) { return INT64(0); } //right == +1 or -1 if (iRSize == 2 && bigData._pData[1] == '1') { std::string ret = this->_ pData; ret [0] = cSign; return ret.c_str ();} / / left = = right if (strcmp (this- > _ pData.c_str () + 1, bigData._pData.c_str () + 1) = = 0) {std::string ret = "+ 1"; ret [0] = cSign Return ret.c_str ();} / / there is an overflow, generally return this- > DivStr (bigData). C_str ();} std::string BigData::DivStr (const BigData& bigData) const {char cSign ='+'; if (this- > _ pData [0]! = bigData._pData [0]) {cSign ='-' } size_t iLsize = this- > _ pData.size (); size_t iRSize = bigData._pData.size (); std::string ret; ret.append (1, cSign); std::string leftStr = this- > _ pData.c_str (); / / otherwise this std::string rightStr = bigData._pData.c_str () Char* left = (char*) (leftStr.c_str () + 1); char* right = (char*) (rightStr.c_str () + 1); int iCount = iRSize-1; while (true) {int slenLeft = strlen (left); int slenRight = strlen (right); if ((slenLeft)
< slenRight) || (slenLeft == slenRight&&strcmp(left, right) < 0)) { break; } if (!IsLeftStrBig(left, iCount, right, iRSize - 1)) //left < right { ret.append(1, '0'); ++iCount; continue; } char ch = LoopSub(left, iCount, right, iRSize - 1); while (*left == '0') { ++left; --iCount; } ++iCount; //取得下一位 ret.append(1, ch); } return ret.c_str();}char BigData::LoopSub(char* pLeft, int iLSize, const char* pRight, int iRSize)const{ char ret = '0'; while (IsLeftStrBig(pLeft, iLSize, pRight, iRSize)) { ret++; for (int i = iLSize - 1; (i >= 0) & & (iRSize + I-iLSize > = 0);-- I) {pLeft [I]-= (pRight [iRSize + I-iLSize] -'0'); if (pLeft [I]
< '0') { pLeft[i] += 10; --pLeft[i - 1]; } }//for //去0 eg:0334 while (*pLeft == '0') { ++pLeft; --iLSize; } }//while return ret;}bool BigData::IsLeftStrBig(const char* pLeft, int iLSize, const char* pRight, int iRSize)const{ if ((iLSize >IRSize) | | (iLSize = = iRSize & & strcmp (pLeft, pRight) > = 0) {return true;} return false;} void BigData::_Int64ToStr () {char cSign ='+'; if (this- > _ value)
< 0) { cSign = '-'; } this->_ pData.append (1, cSign); if (this- > _ value = = 0) {this- > _ pData.append (1,'0'); return;} INT64 temp = this- > _ value; while (temp) {this- > _ pData.append (1, (temp% 10 +'0')) Temp / = 10;} char* left = (char*) (this- > _ pData.c_str () + 1); char* right = left + this- > _ pData.size ()-2; while (left
< right) { char ch = *left; *left++ = *right; *right-- = ch; }}/*void BigData::_Int64ToStr()*/bool BigData::_IsINT64OverFlow()const{ std::string max = "+9223372036854775807"; std::string min = "-9223372036854775808"; size_t size = this->_ pData.size (); if (size
< max.size()) { return true; } if ((this->_ pData [0] = ='+') & & (size = = max.size ()) & & (this- > _ pData _ pData [0] = ='-') & (size = = min.size ()) & & (this- > _ pData