项目名称 大数计算器
*************************************************
大数计算的底层采用string对象存储, 将整型数据转换为字符型进行存储运算的加减;采用逐位进行加减, 设计标记位, 标记进位与借位的方式;乘除在加减的基础上控制循环的次数完成对数据的处理
#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 0x7fffffffffffffff class 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 = ‘-‘; else cSymbol = ‘+‘; } 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; }
时间: 2024-10-20 20:36:25