標籤:大資料加減乘除
項目名稱 大數計算機
*************************************************
大數計算的底層採用stringObject Storage Service, 將整型資料轉換為字元型進行儲存運算的加減;採用逐位進行加減, 設計標記位, 標記進位與借位的方式;乘除在加減的基礎上控制迴圈的次數完成對資料的處理
#include<iostream>#include<cassert>#include<string>using namespace std;#define INT_64 long long#define UN_INIT 0xcccccccccccccccc//不能分開#define MIN_INT 0xffffffffffffffff#define MAX_INT 0x7fffffffffffffffclass BigData{public:BigData():_data(0), _pdata(""){}BigData(INT_64 data):_data(data){INT_64 tmp = _data;char cSymbol = ‘+‘;if (tmp<0){tmp = 0 - tmp;cSymbol = ‘-‘;}_pdata.append(1, cSymbol);while (tmp){_pdata.append(1, tmp % 10 + ‘0‘);tmp /= 10;}char* left = (char*)(_pdata.c_str() + 1);char* right = (char*)(_pdata.c_str() + _pdata.size() - 1);char temp;while (left < right){temp = *left;*left++ = *right;*right-- = temp;}}BigData(const char* pData){assert(pData);INT_64 ret = 0;char* source = (char*)pData;char cSymbol = ‘+‘;if (*source == ‘-‘ || *source == ‘+‘)cSymbol = *source;//while (*source == ‘0‘)//source++;_pdata.append(1, cSymbol);while (*source <= ‘9‘&&*source >= ‘0‘){if (ret <= MAX_INT)ret = ret * 10 + *source;_pdata.append(1, *source);source++;}if (*source = ‘-‘)ret = 0 - ret;_data = ret;}BigData(const BigData& bigData){_data = bigData._data;_pdata = bigData._pdata;}BigData operator+(BigData& bigData){if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow()){if (_pdata[0] != bigData._pdata[0])return BigData(_data + bigData._data);else{if (‘+‘ == _pdata[0] && MAX_INT - _data <= bigData._data || ‘-‘ == _pdata[0] && _data >= MIN_INT - bigData._data)return BigData(_data + bigData._data);}}return BigData(Add(_pdata, bigData._pdata).c_str());}BigData operator-(BigData& bigData){if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow()){if (_pdata[0] == bigData._pdata[0])return BigData(_data - bigData._data);else{if (‘+‘ == _pdata[0] && _data <= MAX_INT + bigData._data || ‘-‘ == _pdata[0] && _data >= MIN_INT + bigData._data)return BigData(_data - bigData._data);}}string ret;if (_pdata[0] == bigData._pdata[0])ret = Sub(_pdata, bigData._pdata);else{ret = Add(_pdata, bigData._pdata);ret[0] = _pdata[0];}return BigData(ret.c_str());}BigData operator*(BigData& bigData){if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow()){if (_pdata[0] == bigData._pdata[0]){if (‘+‘ == _pdata[0] && _data <= MAX_INT / bigData._data || ‘-‘ == _pdata[0] && _data >= MAX_INT / bigData._data)return BigData(_data *bigData._data);}else{if (‘+‘ == _pdata[0] && _data <= MIN_INT / bigData._data || ‘-‘ == _pdata[0] && _data >= MIN_INT / bigData._data)return BigData(_data * bigData._data);}}return BigData(Mul(_pdata, bigData._pdata).c_str());}BigData operator/(BigData& bigData){if (_data == 0 || bigData._data == 0)return BigData(INT_64(0));if (!IsINT64OverFlow() && !bigData.IsINT64OverFlow()){return BigData(_data / bigData._data);}return BigData(Div(_pdata, bigData._pdata).c_str());}friend ostream& operator<<(ostream& out, const BigData& b){out << b._pdata;return out;}friend istream& operator>>(istream& in, BigData& b){in >> b._pdata;return in;}protected:bool IsINT64OverFlow(){if (_data <= MAX_INT&&_data >= MIN_INT)return false;return true;}string Add(string s1, string s2){int leftSize = s1.size();int rightSize = s2.size();string ret;char cSymbol = ‘+‘;if (s1[0] == s2[0]){if (s1[0] == ‘-‘)cSymbol = ‘-‘;}else{if (s1[0] == ‘+‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0 || s1[0] == ‘-‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1)>0)cSymbol = ‘-‘;}if (leftSize < rightSize){swap(s1, s2);swap(leftSize, rightSize);}ret.resize(leftSize + 1);ret[0] = cSymbol;char cRes, cStep = 0;for (int idx = 1; idx < leftSize; ++idx){cRes = s1[leftSize - idx] - ‘0‘ + cStep;if (idx<rightSize)cRes += (s2[rightSize - idx] - ‘0‘);cStep = cRes / 10;ret[leftSize - idx + 1] = cRes % 10 + ‘0‘;}ret[1] = cStep + ‘0‘;return ret;}string Sub(string s1, string s2){int leftSize = s1.size();int rightSize = s2.size();char cSymbol = s1[0];//leftSize == rightSize &&(cSymbol == ‘+‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0 || cSymbol == ‘-‘&&strcmp(s1.c_str() + 1, s2.c_str() + 1) > 0)if (leftSize < rightSize || leftSize == rightSize &&strcmp(s1.c_str() + 1, s2.c_str() + 1) < 0){swap(s1, s2);swap(leftSize, rightSize);if (‘+‘ == cSymbol)cSymbol = ‘-‘;elsecSymbol = ‘+‘;}string ret;ret.resize(leftSize);ret[0] = cSymbol;char cRet;for (int idx = 1; idx < leftSize; ++idx){cRet = s1[leftSize - idx] - ‘0‘;if (idx < rightSize)cRet -= (s2[rightSize - idx] - ‘0‘);if (cRet < 0){s1[leftSize - idx - 1] -= 1;cRet += 10;}ret[leftSize - idx] = cRet + ‘0‘;}return ret;}string Mul(string s1, string s2){int leftSize = s1.size();int rightSize = s2.size();if (leftSize < rightSize){swap(leftSize, rightSize);swap(s1, s2);}char cSymbol = ‘+‘;if (s1[0] != s2[0])cSymbol = ‘-‘;string ret;ret.resize(leftSize + rightSize - 1);ret[0] = cSymbol;int iDataLen = ret.size();int offSet = 0;for (int idx = 1; idx < rightSize; ++idx){char cLeft = s2[rightSize - idx] - ‘0‘;char cStep = 0;if (cLeft == 0){++offSet;continue;}for (int iLdx = 1; iLdx < leftSize; ++iLdx){char cRet = cLeft*(s1[leftSize - iLdx] - ‘0‘);cRet += (cStep + ret[iDataLen - iLdx - offSet] - ‘0‘);ret[iDataLen - iLdx - offSet] = cRet % 10 + ‘0‘;cStep = cRet / 10;}ret[iDataLen - offSet - leftSize] += cStep;++offSet;}return ret;}string Div(string s1, string s2){int leftSize = s1.size();int rightSize = s2.size();char cSymbol = ‘+‘;if (s1[0] != s2[0]){cSymbol = ‘-‘;}if (leftSize < rightSize || (leftSize == rightSize&&strcmp(s1.c_str() + 1, s2.c_str() + 1))){return "0";}else{if ("1" == s2 || "-1" == s2){s1[0] = cSymbol;return s1;}}char *left = (char*)(s1.c_str() + 1);char* right = (char*)(s2.c_str() + 1);int iDataLen = rightSize - 1;string ret;for (int idx = 0; idx < leftSize - 1; ++idx){if (!IsLeftStrRight(left, iDataLen, right, rightSize - 1)){iDataLen++;ret.append(1, ‘0‘);continue;}else{ret.append(1, SubLoop(left, iDataLen, right, rightSize - 1));iDataLen = rightSize - 1;}}}char SubLoop(char*& left, int lSize, char* right, int rSize){assert(left&&right);char cRet = ‘0‘;while (1){if (!IsLeftStrRight(left, lSize, right, rSize))break;int lDataLen = lSize;int rDataLen = rSize;while (lDataLen >= 0 && rDataLen >= 0){if (left[lDataLen] < right[rDataLen]){left[lDataLen - 1] -= 1;left[lDataLen] += 10;}left[lDataLen] -= right[rDataLen];lDataLen--;rDataLen--;}while (‘0‘ == *left){left++;lSize--;}cRet++;}}bool IsLeftStrRight(char* left, int lSize, char* right, const int rSize){assert(left&&right);if (lSize>rSize || lSize == rSize&&strncmp(left, right, lSize) >= 0)return true;return false;}private:INT_64 _data;string _pdata;};void Test1(){BigData b1(1234);BigData b2(123456789);BigData b3= b1 + b2;cout << b3 << endl;}
本文出自 “小止” 部落格,請務必保留此出處http://10541556.blog.51cto.com/10531556/1767620
類比大資料的基本計算, 以解決常規計算機計算資料時位元的有限性