標籤:大資料的運算 加 減 乘 除
BigData.h:
#ifndef __BIG_DATA_H__#define __BIG_DATA_H__#include <assert.h>#include <string>typedef long long INT64;//#define MININT64 -9223372036854775808 // 編譯器檢查有錯////#define MAXINT64 +9223372036854775807 const INT64 MININT64 = +9223372036854775807 + 1;const INT64 MAXINT64 = +9223372036854775807;class BigData{friend std::ostream& operator<<(std::ostream& _cout, const BigData& bigData);public:BigData(INT64 value = 0xCCCCCCCCCCCCCCCC);BigData(const char* str);BigData operator+(const BigData& bigData);BigData operator-(const BigData& bigData);BigData operator*(const BigData& bigdata);BigData operator/(const BigData& bigdata);protected:void _Int64ToStr();bool _IsINT64OverFlow()const;std::string AddStr(const BigData& bigData)const;std::string SubStr(const BigData& bigData)const;std::string MulStr(const BigData& bigData)const;std::string DivStr(const BigData& bigData)const;bool IsLeftStrBig(const char* pLeft, int iLSize, const char* pRight, int iRSize)const;char LoopSub(char* pLeft, int iLSize, const char* pRight, int iRSize)const;private:INT64 _value;std::string _pData;}; std::ostream& operator<<(std::ostream& _cout, const BigData& bigData);#endif /*__BIG_DATA_H__*/
BigData.cpp:
#define _CRT_SECURE_NO_WARNINGS 1#include "BigData.h"BigData::BigData(INT64 value) :_value(value){this->_Int64ToStr();}BigData::BigData(const char* str) : _value(0){assert(str);char* temp = (char*)str;char cSign = ‘+‘;while (isspace(*temp)) //*temp == ‘ ‘不能消除tab{++temp;}if ((*temp == ‘-‘) || (*temp == ‘+‘)){cSign = *temp;++temp;}this->_pData.resize(strlen(str) + 1);this->_pData[0] = cSign;int iCount = 1;while (*temp == ‘0‘)//處理000123{++temp;}while ((*temp >= ‘0‘) && (*temp <= ‘9‘)){this->_value = this->_value * 10 + (*temp - ‘0‘);this->_pData[iCount++] = *temp++;}this->_pData.resize(iCount);if (cSign == ‘-‘){this->_value = 0 - this->_value;}if (!this->_IsINT64OverFlow())//溢出{this->_value = 0xCCCCCCCCCCCCCCCC;}}/*BigData(const char* str)*/BigData BigData::operator+(const BigData& bigData){if (this->_IsINT64OverFlow() && bigData._IsINT64OverFlow()) //兩個均沒有溢出{if (this->_pData[0] != bigData._pData[0])//異號,相加肯定沒有溢出{return BigData(this->_value + bigData._value);}else //兩個同號{if ((this->_value>0 && MAXINT64 - this->_value >= bigData._value) || //結果仍沒有溢出(this->_value<0 && MININT64 - this->_value <= bigData._value)){return BigData(this->_value + bigData._value);}}}if (this->_pData[0] == bigData._pData[0]) //兩個同號{return BigData(this->AddStr(bigData).c_str());}BigData temp1((this->_pData).c_str()); //有溢出,異號,調用減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())//無溢出{if (this->_pData[0] == bigData._pData[0]) //同號,相減後肯定無溢出{return this->_value - bigData._value;}else{if ((this->_value > 0 && MAXINT64 + bigData._value >= this->_value)||(this->_value < 0 && MININT64 + bigData._value <= this->_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()); //異號,有溢出 -3-5=-3+(-5) 3-(-5)=3+5temp._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()) //沒溢出{if ((cSign == ‘+‘) && //同號且結果沒溢出((this->_value > 0 && MAXINT64 / this->_value >= bigData._value) ||(this->_value < 0 && MAXINT64 / this->_value <= bigData._value))){return this->_value * bigData._value;}if ((cSign == ‘-‘) && //異號且結果沒溢出((this->_value > 0 && MININT64 / this->_value <= bigData._value) ||(this->_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 == 0if (bigData._pData[1] == ‘0‘)assert(false);//left == 0if (this->_pData[1] == ‘0‘){return INT64(0);}//無溢出,結果肯定無溢出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 < rightif ((iLSize < iRSize) || (iLSize == iRSize && strcmp(this->_pData.c_str() + 1, bigData._pData.c_str() + 1) < 0)){return INT64(0);}//right == +1 or -1if (iRSize == 2 && bigData._pData[1] == ‘1‘){std::string ret = this->_pData;ret[0] = cSign;return ret.c_str();}//left == rightif (strcmp(this->_pData.c_str() + 1, bigData._pData.c_str() + 1) == 0){std::string ret = "+1";ret[0] = cSign;return ret.c_str();}//有溢出,一般情況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(); //否則會改變thisstd::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:0334while (*pLeft == ‘0‘){++pLeft;--iLSize;}}//whilereturn 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 <= max)){return true;//返回true沒有溢出}if ((this->_pData[0] == ‘-‘) && (size == min.size()) && (this->_pData <= min)){return true;}return false;}/*bool BigData::_IsINT64OverFlow()const*/std::ostream& operator<<(std::ostream& _cout, const BigData& bigData){if (bigData._IsINT64OverFlow())//沒有溢出{_cout << bigData._value << std::endl;}else{if (bigData._pData[0] == ‘+‘){_cout << bigData._pData.c_str() + 1 << std::endl;}else{_cout << bigData._pData << std::endl;}}return _cout;}
大資料的運算加減乘除