您的位置:首页 > 大数据

模拟大数据的基本计算, 以解决常规计算器计算数据时位数的有限性

2016-04-25 18:27 417 查看
项目名称 大数计算器
*************************************************大数计算的底层采用string对象存储, 将整型数据转换为字符型进行存储运算的加减;采用逐位进行加减, 设计标记位, 标记进位与借位的方式;乘除在加减的基础上控制循环的次数完成对数据的处理
#include<iostream>
#include<cassert>
#include<string.h>
#include<string>
using namespace std;
#define INT_64 long long
#define UN_INIT  0xcccccccccccccccc//不能分开
#define MIN_INT  0xffffffffffffffff
#define MAX_INT  (unsigned)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;
}
cout<<_data<<_pdata<<endl;
}
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-'0';
_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())
{
cout<<"pppp";
if (_pdata[0] == bigData._pdata[0])
{
if ('+' == _pdata[0] && _data <= (MAX_INT / bigData._data )|| '-' == _pdata[0] && _data >= MAX_INT / bigData._data)
{
cout<<(_data*bigData._data)<<"KKKKK";
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);
}
}
cout<<"KKKKKKKKll";
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)
{
cout<<"normal"<<endl;
return false;
}
cout<<"haha"<<endl;
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);
memset((void*)ret.c_str(),'0',ret.size()*sizeof(char));
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;
}
//cout<<ret;
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);
left[leftSize-1]='\0';
char* right = (char*)(s2.c_str() + 1);
right[rightSize-1]='\0';
int iDataLen = rightSize-1;
string ret;
ret[0]=cSymbol;
int idx;
for (idx = 0; idx < leftSize-1;++idx)
{
cout<<"idx"<<left<<endl;
if (!IsLeftStrRight(left, iDataLen, right, rightSize - 1))
{
iDataLen++;
ret.append(1, '0');
continue;
}
else
{
cout<<"SubLoop"<<left<<endl;
ret.append(1, SubLoop(left, iDataLen, right, rightSize - 1));
cout<<"after"<<left<<endl;
iDataLen+=rightSize-1;
}
}
return ret;
}
char SubLoop(char*& left, int& lSize, char* right, int rSize)
{
assert(left&&right);
char cRet = '0';
//int srcLeft=lSize;
while (1)
{
if (!IsLeftStrRight(left, lSize, right, rSize))
{
cout<<"false:"<<cRet<<"left"<<left<<endl;
break;
}
cout<<"while"<<left<<"cRet"<<cRet<<endl;
int lDataLen = lSize-1;
int rDataLen = rSize-1;
while (lDataLen >= 0 && rDataLen >= 0)
{
if (left[lDataLen] < right[rDataLen])
{
if(lDataLen<1)
break;
left[lDataLen - 1] -= 1;
left[lDataLen] += 10;
}
left[lDataLen] -= right[rDataLen];
left[lDataLen]+='0';
lDataLen--;
rDataLen--;
}
cout<<left<<endl;
while ('0' == *left)
{
left++;
lSize--;
}
cRet++;
}
return 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;
};
int main()
{
//   BigData b1(102);
// BigData b2(3);
//BigData  b3= b1 /b2;
//cout << b3 << endl;
cout<<(123<=(signed)0x7fffffffffffffff)<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  加减乘除 大数据